24
.afignore
Normal file
@ -0,0 +1,24 @@
|
||||
#ignore database
|
||||
b-cov
|
||||
*.seed
|
||||
*.log
|
||||
*.csv
|
||||
*.dat
|
||||
*.out
|
||||
*.pid
|
||||
*.gz
|
||||
|
||||
pids
|
||||
logs
|
||||
results
|
||||
|
||||
npm-debug.log
|
||||
|
||||
.idea/*
|
||||
*.iml
|
||||
projectFilesBackup
|
||||
|
||||
.DS_Store
|
||||
|
||||
# Ghost DB file
|
||||
ghost/data/*.db
|
31
.gitignore
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
b-cov
|
||||
*.seed
|
||||
*.log
|
||||
*.csv
|
||||
*.dat
|
||||
*.out
|
||||
*.pid
|
||||
*.gz
|
||||
|
||||
pids
|
||||
logs
|
||||
results
|
||||
|
||||
npm-debug.log
|
||||
node_modules
|
||||
|
||||
.idea/*
|
||||
*.iml
|
||||
projectFilesBackup
|
||||
|
||||
.DS_Store
|
||||
|
||||
# Ghost DB file
|
||||
*.db
|
||||
|
||||
/core/admin/assets/css
|
||||
.sass-cache/
|
||||
/core/admin/assets/sass/config.rb
|
||||
/core/admin/assets/sass/layouts/config.rb
|
||||
/core/admin/assets/sass/modules/config.rb
|
||||
/ghost/.idea/
|
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "content/themes/casper"]
|
||||
path = content/themes/casper
|
||||
url = git@github.com:TryGhost/Casper.git
|
5
.groc.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"glob": ["README.md", "config.js", "app.js", "core/ghost.js", "core/admin/assets/js/*.js", "core/frontend/helpers/index.js", "core/lang/i18n.js"],
|
||||
"except": ["core/admin/assets/lib/chart.min.js"],
|
||||
"out": "./docs"
|
||||
}
|
22
LICENSE
Normal file
@ -0,0 +1,22 @@
|
||||
Copyright (c) 2013 Ghost
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
87
README.md
@ -1,2 +1,85 @@
|
||||
Ghost
|
||||
=====
|
||||
# Ghost
|
||||
|
||||
Welcome to the Ghost core repo. The code here is the result of a few stolen hours of free time hacking a proof of concept for the Kickstarter video. Pretty much everything is subject to and expected to change.
|
||||
|
||||
The top priorities right now are:
|
||||
|
||||
* Having a core RESTful API and consuming it internally
|
||||
* Data model design & implementation - including a potential switch from JugglingDB to bookshelf.js
|
||||
* Authentication and ACL
|
||||
* Improving core architecture & design - modular structure, better dependency injection, testable code with tests
|
||||
|
||||
|
||||
|
||||
###To Install:
|
||||
|
||||
**Note:** It is highly recommended that you use the [Ghost-Vagrant](https://github.com/TryGhost/Ghost-Vagrant) setup for developing Ghost.
|
||||
|
||||
1. Clone the git repo
|
||||
1. cd into the project folder and run ```npm install```.
|
||||
* If the install fails with errors to do with "node-gyp rebuild", follow the Sqlite3 install instructions
|
||||
1. cd into /core/admin/assets and run ```compass compile --css-dir=css```
|
||||
|
||||
|
||||
Frontend can be located at [localhost:3333](localhost:3333), Admin is at [localhost:3333/ghost](localhost:3333/ghost)
|
||||
|
||||
|
||||
#### Sqlite3 Install Instructions
|
||||
Ghost depends upon sqlite3, which has to be built for each OS. NPM is as smart as it can be about this, and as long as your machine has all the pre-requisites for compiling/building a C++ program, the npm install still works.
|
||||
|
||||
However, if you don't have the required pre-requisites, you will need to either get them, or as a shortcut, obtain a precompiled sqlite3 package for your OS.
|
||||
|
||||
I have created some of these, and they can be obtained from [this GitHub issue](https://github.com/developmentseed/node-sqlite3/issues/106).
|
||||
|
||||
The pre-compiled package should be downloaded, extracted and placed in the node\_modules folder, such that it lives in node\_modules/sqlite3, if you have a partial install of the sqlite3 package, replace it with the files you downloaded from github. Be sure that all the sqlite3 files and folders live directly in node\_modules/sqlite3 - there should note be a node\_modules/sqlite3/sqlite3 folder.
|
||||
|
||||
|
||||
###Dependencies:
|
||||
|
||||
* express.js framework
|
||||
* handlebars for templating
|
||||
* standard css for frontend
|
||||
* sass for admin (pre-compiled)
|
||||
* moment.js for time / date manipulation
|
||||
* underscore for object & array utils
|
||||
* showdown for converting markdown to HTML
|
||||
* nodeunit for unit testing
|
||||
* sqlite3 for data storage
|
||||
* jugglingdb ORM for interacting with the database
|
||||
* Polyglot.js for i18n
|
||||
|
||||
#### Frontend libraries:
|
||||
|
||||
* jQuery 1.9.1
|
||||
* showdown for converting markdown to HTML
|
||||
* codemirror editor
|
||||
|
||||
### Working features:
|
||||
|
||||
* Dashboard
|
||||
* new post link
|
||||
* Admin menu
|
||||
* G, dashboard, content, new post & settings menu items go to correct pages
|
||||
* Content screen
|
||||
* Lists all posts with correct titles (incorrect time etc)
|
||||
* Select post in list highlights that post and opens it in the preview pane
|
||||
* Write screen
|
||||
* Live preview works for all standard markdown
|
||||
* Save draft button saves entered title & content. Everything is published by default.
|
||||
* Editing/opening existing post puts correct info in title and content panels & save updates content.
|
||||
* Database
|
||||
* The database is created and populated with basic data on first run of the server
|
||||
* New posts and edits save and last forever
|
||||
* The data can be reset by opening data/datastore.db and emptying the file. The next restart of the server will cause the database to be recreated and repopulated.
|
||||
* Frontend
|
||||
* Homepage lists a number of posts as configured in config.js
|
||||
* Clicking on an individual post loads an individual post page
|
||||
* Date formatting helper uses moment
|
||||
|
||||
### Front End Work
|
||||
|
||||
A SASS compiler is required to work with the CSS in this project.
|
||||
|
||||
Run ```compass compile --css-dir=css``` from /core/admin/assets.
|
||||
|
||||
We also recommend [CodeKit](http://incident57.com/codekit/) (Paid/Mac) and [Scout](http://mhs.github.io/scout-app/) (Free/Mac/PC).
|
80
app.js
Normal file
@ -0,0 +1,80 @@
|
||||
// # Ghost main app file
|
||||
|
||||
/*global require */
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
// Module dependencies.
|
||||
var express = require('express'),
|
||||
fs = require('fs'),
|
||||
admin = require('./core/admin/controllers'),
|
||||
frontend = require('./core/frontend/controllers'),
|
||||
flash = require('connect-flash'),
|
||||
Ghost = require('./core/ghost'),
|
||||
I18n = require('./core/lang/i18n'),
|
||||
helpers = require('./core/frontend/helpers'),
|
||||
auth,
|
||||
|
||||
// ## Variables
|
||||
/**
|
||||
* Create new Ghost object
|
||||
* @type {Ghost}
|
||||
*/
|
||||
ghost = new Ghost();
|
||||
|
||||
ghost.app().configure('development', function () {
|
||||
ghost.app().use(express.favicon(__dirname + '/content/images/favicon.ico'));
|
||||
ghost.app().use(express.errorHandler());
|
||||
ghost.app().use(I18n.load(ghost));
|
||||
ghost.app().use(express.bodyParser());
|
||||
ghost.app().use(express.cookieParser('try-ghost'));
|
||||
ghost.app().use(express.session({ cookie: { maxAge: 60000 }}));
|
||||
ghost.app().use(flash());
|
||||
ghost.app().use(ghost.initTheme(ghost.app()));
|
||||
});
|
||||
|
||||
/**
|
||||
* Setup login details
|
||||
* p.s. love it.
|
||||
*
|
||||
* @type {*}
|
||||
*/
|
||||
auth = express.basicAuth('ghostadmin', 'Wh0YouGonnaCall?');
|
||||
|
||||
helpers.loadCoreHelpers(ghost);
|
||||
|
||||
|
||||
/**
|
||||
* API routes..
|
||||
* @todo convert these into a RESTful, public, authenticated API!
|
||||
*/
|
||||
ghost.app().post('/api/v0.1/posts/create', auth, admin.posts.create);
|
||||
ghost.app().post('/api/v0.1/posts/edit', auth, admin.posts.edit);
|
||||
ghost.app().get('/api/v0.1/posts', auth, admin.posts.index);
|
||||
|
||||
/**
|
||||
* Admin routes..
|
||||
* @todo put these somewhere in admin
|
||||
*/
|
||||
ghost.app().get('/ghost/editor/:id', auth, admin.editor);
|
||||
ghost.app().get('/ghost/editor', auth, admin.editor);
|
||||
ghost.app().get('/ghost/blog', auth, admin.blog);
|
||||
ghost.app().get('/ghost/settings', auth, admin.settings);
|
||||
ghost.app().get('/ghost/debug', auth, admin.debug.index);
|
||||
ghost.app().get('/ghost/debug/db/delete/', auth, admin.debug.dbdelete);
|
||||
ghost.app().get('/ghost/debug/db/populate/', auth, admin.debug.dbpopulate);
|
||||
ghost.app().get('/ghost', auth, admin.index);
|
||||
|
||||
/**
|
||||
* Frontend routes..
|
||||
* @todo dynamic routing, homepage generator, filters ETC ETC
|
||||
*/
|
||||
ghost.app().get('/:slug', frontend.single);
|
||||
ghost.app().get('/', frontend.homepage);
|
||||
|
||||
|
||||
ghost.app().listen(3333, function () {
|
||||
console.log("Express server listening on port " + 3333);
|
||||
console.log('process: ', process.env);
|
||||
});
|
||||
}());
|
62
config.js
Normal file
@ -0,0 +1,62 @@
|
||||
// # Ghost Configuration
|
||||
|
||||
/**
|
||||
* global module
|
||||
**/
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @module config
|
||||
* @type {Object}
|
||||
*/
|
||||
var config = {};
|
||||
|
||||
// ## Admin settings
|
||||
|
||||
/**
|
||||
* @property {string} defaultLang
|
||||
*/
|
||||
config.defaultLang = 'en';
|
||||
|
||||
/**
|
||||
* @property {boolean} forceI18n
|
||||
*/
|
||||
config.forceI18n = true;
|
||||
|
||||
// ## Themes
|
||||
|
||||
/**
|
||||
* @property {string} themeDir
|
||||
*/
|
||||
|
||||
// Themes
|
||||
config.themeDir = 'themes';
|
||||
|
||||
/**
|
||||
* @property {string} activeTheme
|
||||
*/
|
||||
config.activeTheme = 'casper';
|
||||
|
||||
// ## Homepage settings
|
||||
/**
|
||||
* @module homepage
|
||||
* @type {Object}
|
||||
*/
|
||||
config.homepage = {};
|
||||
|
||||
/**
|
||||
* @property {number} features
|
||||
*/
|
||||
config.homepage.features = 1;
|
||||
|
||||
/**
|
||||
* @property {number} posts
|
||||
*/
|
||||
config.homepage.posts = 4;
|
||||
|
||||
/**
|
||||
* @property {Object} exports
|
||||
*/
|
||||
module.exports = config;
|
||||
}());
|
26
config.rb
Normal file
@ -0,0 +1,26 @@
|
||||
# Require any additional compass plugins here.
|
||||
|
||||
|
||||
# Set this to the root of your project when deployed:
|
||||
http_path = "/"
|
||||
css_dir = "core/admin/assets/css"
|
||||
sass_dir = "core/admin/assets/sass"
|
||||
images_dir = "core/admin/assets/img"
|
||||
javascripts_dir = "core/admin/assets/js"
|
||||
fonts_dir = "core/admin/assets/fonts"
|
||||
|
||||
output_style = :nested
|
||||
|
||||
# To enable relative paths to assets via compass helper functions. Uncomment:
|
||||
# relative_assets = true
|
||||
|
||||
# To disable debugging comments that display the original location of your selectors. Uncomment:
|
||||
# line_comments = false
|
||||
color_output = false
|
||||
|
||||
|
||||
# If you prefer the indented syntax, you might want to regenerate this
|
||||
# project again passing --syntax sass, or you can uncomment this:
|
||||
# preferred_syntax = :sass
|
||||
# and then run:
|
||||
# sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass
|
13
content/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
#Content
|
||||
|
||||
This section of the repo is the area that a normal user is allowed to add and change stuff. This is where their themes, plugins and images will live.
|
||||
|
||||
By default for an install:
|
||||
|
||||
* the themes directory will contain Casper
|
||||
* the plugins directory will be empty
|
||||
* the images directory will be empty
|
||||
|
||||
Currently the plugins and images directory contain some stuff for testing.
|
||||
|
||||
By default, Ghost will support very basic image uploads. It will be expected and encouraged for users to connect to a 3rd party service for improved media support and a CDN. Much like comments, we don't see supporting advanced file uploads, having a media library or being a CDN as core competencies - there are already plenty of people out there doing this much better than we can.
|
BIN
content/images/DSCF1202-1-800x420.jpg
Normal file
After Width: | Height: | Size: 46 KiB |
BIN
content/images/DSCF1308-800x420.jpg
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
content/images/DSCF1703-800x420.jpg
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
content/images/Egypt-Vimeo-Cover-800x420.jpg
Normal file
After Width: | Height: | Size: 77 KiB |
BIN
content/images/depostimg.jpg
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
content/images/favicon.ico
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
content/images/ghost-dashboard.jpg
Normal file
After Width: | Height: | Size: 83 KiB |
BIN
content/images/ghostpost.jpg
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
content/images/logo.png
Normal file
After Width: | Height: | Size: 26 KiB |
45
content/plugins/fancyFirstChar.js
Normal file
@ -0,0 +1,45 @@
|
||||
/*globals exports */
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var FancyFirstChar;
|
||||
|
||||
FancyFirstChar = function (ghost) {
|
||||
this.ghost = function () {
|
||||
return ghost;
|
||||
};
|
||||
};
|
||||
FancyFirstChar.prototype.init = function () {
|
||||
this.ghost().registerFilter('prePostsRender', function (posts) {
|
||||
var post,
|
||||
originalContent,
|
||||
newContent,
|
||||
firstCharIndex = 0;
|
||||
|
||||
console.log('got content to filter', posts);
|
||||
|
||||
for (post in posts) {
|
||||
if (posts.hasOwnProperty(post)) {
|
||||
originalContent = posts[post].content;
|
||||
if (originalContent.substr(0, 1) === '<') {
|
||||
firstCharIndex = originalContent.indexOf('>') + 1;
|
||||
}
|
||||
|
||||
newContent = originalContent.substr(0, firstCharIndex);
|
||||
newContent += '<span class="fancyChar">';
|
||||
newContent += originalContent.substr(firstCharIndex, 1);
|
||||
newContent += '</span>';
|
||||
newContent += originalContent.substr(firstCharIndex + 1, originalContent.length - firstCharIndex - 1);
|
||||
|
||||
posts[post].content = newContent;
|
||||
}
|
||||
}
|
||||
return posts;
|
||||
});
|
||||
};
|
||||
|
||||
FancyFirstChar.prototype.activate = function () {};
|
||||
FancyFirstChar.prototype.deactivate = function () {};
|
||||
|
||||
module.exports = FancyFirstChar;
|
||||
}());
|
1
content/themes/casper
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 151f5d3f4c3b613a283a0733ffd1f97f403f477c
|
12
core/README.md
Normal file
@ -0,0 +1,12 @@
|
||||
# Core
|
||||
|
||||
Core contains the bread and butter of ghost. It is currently divided up into:
|
||||
|
||||
* **admin** - the views, controllers, assets and helpers for rendering & working the admin panel
|
||||
* **frontend** - the controllers & helpers for creating the frontend of the blog. Views & assets live in themes
|
||||
* **lang** - the current home of everything i18n, this was done as a proof of concept on a very early version of the prototype and needs love
|
||||
* **shared** - basically everything to do with data & models. The sqlite db file lives in the data folder here. This is the part that needs the most work so it doesn't make much sense yet, and is also the highest priority
|
||||
* **test** - currently contains two sad unit tests and a set of html prototypes of the admin UI. Really, this folder should reflect all of core. It is my personal mission to make that happen ASAP & get us linked up with Travis.
|
||||
* **ghost.js** - currently both the glue that binds everything together and what gives us the API for registering themes and plugins. The initTheme function is a bit of a hack which lets us serve different views & static content up for the admin & frontend.
|
||||
|
||||
This structure is by no means final and recommendations are more than welcome.
|
196
core/admin/assets/fonts/icons.dev.svg
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
core/admin/assets/fonts/icons.eot
Normal file
196
core/admin/assets/fonts/icons.svg
Normal file
After Width: | Height: | Size: 51 KiB |
BIN
core/admin/assets/fonts/icons.ttf
Normal file
BIN
core/admin/assets/fonts/icons.woff
Normal file
BIN
core/admin/assets/img/dash/CampaignMonitor@2x.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
core/admin/assets/img/dash/Facebook@2x.png
Normal file
After Width: | Height: | Size: 122 KiB |
BIN
core/admin/assets/img/dash/GooglePlus@2x.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
core/admin/assets/img/dash/Image@2x.png
Normal file
After Width: | Height: | Size: 1.7 MiB |
BIN
core/admin/assets/img/dash/PostsStats@2x.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
core/admin/assets/img/dash/Stats@2x.png
Normal file
After Width: | Height: | Size: 98 KiB |
BIN
core/admin/assets/img/dash/Time@2x.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
core/admin/assets/img/dash/Twitter@2x.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
core/admin/assets/img/ghost-icon.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
core/admin/assets/img/logo.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
core/admin/assets/img/postimg.jpg
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
core/admin/assets/img/test-icon.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
core/admin/assets/img/user.jpg
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
core/admin/assets/img/users.png
Normal file
After Width: | Height: | Size: 54 KiB |
75
core/admin/assets/js/admin-ui-temp.js
Normal file
@ -0,0 +1,75 @@
|
||||
// # Temporary Admin UI
|
||||
|
||||
/*global document, jQuery */
|
||||
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
// UTILS
|
||||
|
||||
/**
|
||||
* Allows to check contents of each element exactly
|
||||
* @param obj
|
||||
* @param index
|
||||
* @param meta
|
||||
* @param stack
|
||||
* @returns {boolean}
|
||||
*/
|
||||
$.expr[":"].containsExact = function (obj, index, meta, stack) {
|
||||
return (obj.textContent || obj.innerText || $(obj).text() || "") === meta[3];
|
||||
};
|
||||
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
// ## Set interactions for all menus
|
||||
// This finds all visible '.overlay' elements and hides them upon clicking away from the element itself.
|
||||
$("body").on('click', function (event) {
|
||||
var $target = $(event.target);
|
||||
if (!$target.parents().is(".overlay:visible") && !$target.is(".overlay:visible")) {
|
||||
$("body").find(".overlay:visible").fadeOut();
|
||||
}
|
||||
});
|
||||
|
||||
// EDITOR / NOTIFICATIONS
|
||||
|
||||
$('.entry-content header, .entry-preview header').on('click', function () {
|
||||
$('.entry-content, .entry-preview').removeClass('active');
|
||||
$(this).closest('section').addClass('active');
|
||||
});
|
||||
|
||||
$('.entry-title .icon-fullscreen').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
$('body').toggleClass('fullscreen');
|
||||
});
|
||||
|
||||
$('.content-list-content li').on('click', function (e) {
|
||||
var $target = $(e.target).closest('li'),
|
||||
$preview = $('.content-preview');
|
||||
$('.content-list-content li').removeClass('active');
|
||||
$target.addClass('active');
|
||||
// *****
|
||||
// this means a *lot* of extra gumpf is in the DOM and should really be done with AJAX when we have proper
|
||||
// data API endpoints
|
||||
// ideally, we need a way to bind data to views properly... backbone marionette, angular, etc
|
||||
// *****
|
||||
//
|
||||
/**
|
||||
* @todo Remove gumpf
|
||||
*/
|
||||
$preview.find('.content-preview-content .wrapper').html($target.data('content'));
|
||||
$preview.find('.post-controls .post-edit').attr('href', '/ghost/editor/' + $target.data('id'));
|
||||
});
|
||||
|
||||
$('.options.up').on('click', function (e) {
|
||||
e.stopPropagation();
|
||||
$(this).next("ul").fadeToggle(200);
|
||||
});
|
||||
|
||||
$('.editor-options').on('click', 'li', function (e) {
|
||||
$('.button-save').data("state", $(this).data("title")).attr('data-state', $(this).data("title")).text($(this).text());
|
||||
$('.editor-options .active').removeClass('active');
|
||||
$(this).addClass('active');
|
||||
});
|
||||
});
|
||||
}(jQuery));
|
27
core/admin/assets/js/blog.js
Normal file
@ -0,0 +1,27 @@
|
||||
/*global window, history, jQuery, Showdown, CodeMirror */
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
// Shadow on Markdown if scrolled
|
||||
$('.content-list-content').on('scroll', function (e) {
|
||||
if ($('.content-list-content').scrollTop() > 10) {
|
||||
$('.content-list').addClass('scrolling');
|
||||
} else {
|
||||
$('.content-list').removeClass('scrolling');
|
||||
}
|
||||
});
|
||||
|
||||
// Shadow on Preview if scrolled
|
||||
$('.content-preview-content').on('scroll', function (e) {
|
||||
if ($('.content-preview-content').scrollTop() > 10) {
|
||||
$('.content-preview').addClass('scrolling');
|
||||
} else {
|
||||
$('.content-preview').removeClass('scrolling');
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}(jQuery));
|
157
core/admin/assets/js/editor.js
Normal file
@ -0,0 +1,157 @@
|
||||
// # Article Editor
|
||||
|
||||
/*global window, document, history, jQuery, Showdown, CodeMirror, shortcut */
|
||||
(function ($, ShowDown, CodeMirror, shortcut) {
|
||||
"use strict";
|
||||
|
||||
// ## Converter Initialisation
|
||||
/**
|
||||
* @property converter
|
||||
* @type {ShowDown.converter}
|
||||
*/
|
||||
// Initialise the Showdown converter for Markdown.
|
||||
// var delay;
|
||||
var converter = new ShowDown.converter({extensions: ['ghostdown']}),
|
||||
editor = CodeMirror.fromTextArea(document.getElementById('entry-markdown'), {
|
||||
mode: 'markdown',
|
||||
tabMode: 'indent',
|
||||
lineWrapping: true
|
||||
});
|
||||
|
||||
// ## Functions
|
||||
/**
|
||||
* @method Update word count
|
||||
* @todo Really not the best way to do things as it includes Markdown formatting along with words
|
||||
* @constructor
|
||||
*/
|
||||
// This updates the word count on the editor preview panel.
|
||||
function updateWordCount() {
|
||||
var wordCount = document.getElementsByClassName('entry-word-count')[0],
|
||||
editorValue = editor.getValue();
|
||||
|
||||
if (editorValue.length) {
|
||||
wordCount.innerHTML = editorValue.match(/\S+/g).length + ' words';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @method updatePreview
|
||||
* @constructor
|
||||
*/
|
||||
// This updates the editor preview panel.
|
||||
// Currently gets called on every key press.
|
||||
// Also trigger word count update
|
||||
function updatePreview() {
|
||||
var preview = document.getElementsByClassName('rendered-markdown')[0];
|
||||
preview.innerHTML = converter.makeHtml(editor.getValue());
|
||||
|
||||
updateWordCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* @method Save
|
||||
* @constructor
|
||||
*/
|
||||
// This method saves a post
|
||||
function save() {
|
||||
var entry = {
|
||||
title: document.getElementById('entry-title').value,
|
||||
markdown: editor.getValue()
|
||||
},
|
||||
urlSegments = window.location.pathname.split('/');
|
||||
|
||||
if (urlSegments[2] === 'editor' && urlSegments[3] && /^[a-zA-Z0-9]+$/.test(urlSegments[2])) {
|
||||
entry.id = urlSegments[3];
|
||||
$.ajax({
|
||||
url: '/api/v0.1/posts/edit',
|
||||
method: 'POST',
|
||||
data: entry,
|
||||
success: function (data) {
|
||||
console.log('response', data);
|
||||
},
|
||||
error: function (error) {
|
||||
console.log('error', error);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$.ajax({
|
||||
url: '/api/v0.1/posts/create',
|
||||
method: 'POST',
|
||||
data: entry,
|
||||
success: function (data) {
|
||||
console.log('response', data);
|
||||
history.pushState(data, '', '/ghost/editor/' + data.id);
|
||||
},
|
||||
error: function (jqXHR, status, error) {
|
||||
var errors = JSON.parse(jqXHR.responseText);
|
||||
console.log('FAILED', errors);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// ## Main Initialisation
|
||||
$(document).ready(function () {
|
||||
|
||||
$('.entry-markdown header, .entry-preview header').click(function (e) {
|
||||
$('.entry-markdown, .entry-preview').removeClass('active');
|
||||
$(e.target).closest('section').addClass('active');
|
||||
});
|
||||
|
||||
editor.on("change", function () {
|
||||
//clearTimeout(delay);
|
||||
//delay = setTimeout(updatePreview, 50);
|
||||
updatePreview();
|
||||
});
|
||||
|
||||
updatePreview();
|
||||
|
||||
$('.button-save').on('click', function () {
|
||||
save();
|
||||
});
|
||||
|
||||
// Sync scrolling
|
||||
function syncScroll(e) {
|
||||
// vars
|
||||
var $codeViewport = $(e.target),
|
||||
$previewViewport = $('.entry-preview-content'),
|
||||
$codeContent = $('.CodeMirror-sizer'),
|
||||
$previewContent = $('.rendered-markdown'),
|
||||
|
||||
// calc position
|
||||
codeHeight = $codeContent.height() - $codeViewport.height(),
|
||||
previewHeight = $previewContent.height() - $previewViewport.height(),
|
||||
ratio = previewHeight / codeHeight,
|
||||
previewPostition = $codeViewport.scrollTop() * ratio;
|
||||
|
||||
// apply new scroll
|
||||
$previewViewport.scrollTop(previewPostition);
|
||||
|
||||
}
|
||||
// TODO: Debounce
|
||||
$('.CodeMirror-scroll').on('scroll', syncScroll);
|
||||
|
||||
// Shadow on Markdown if scrolled
|
||||
$('.CodeMirror-scroll').on('scroll', function (e) {
|
||||
if ($('.CodeMirror-scroll').scrollTop() > 10) {
|
||||
$('.entry-markdown').addClass('scrolling');
|
||||
} else {
|
||||
$('.entry-markdown').removeClass('scrolling');
|
||||
}
|
||||
});
|
||||
// Shadow on Preview if scrolled
|
||||
$('.entry-preview-content').on('scroll', function (e) {
|
||||
if ($('.entry-preview-content').scrollTop() > 10) {
|
||||
$('.entry-preview').addClass('scrolling');
|
||||
} else {
|
||||
$('.entry-preview').removeClass('scrolling');
|
||||
}
|
||||
});
|
||||
|
||||
// Zen writing mode
|
||||
shortcut.add("Alt+Shift+Z", function () {
|
||||
$('body').toggleClass('zen');
|
||||
});
|
||||
|
||||
});
|
||||
}(jQuery, Showdown, CodeMirror, shortcut));
|
21
core/admin/assets/js/settings.js
Normal file
@ -0,0 +1,21 @@
|
||||
/*globals document, jQuery */
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
var changePage = function (e) {
|
||||
var newPage = $(this).children('a').attr('href');
|
||||
|
||||
e.preventDefault();
|
||||
$('.settings-menu .active').removeClass('active');
|
||||
$(this).addClass('active');
|
||||
|
||||
$('.settings-content').fadeOut().delay(250);
|
||||
$(newPage).fadeIn();
|
||||
|
||||
};
|
||||
|
||||
$(document).ready(function() {
|
||||
$('.settings-menu li').on('click', changePage);
|
||||
});
|
||||
|
||||
}(jQuery));
|
196
core/admin/assets/js/tagui.js
Normal file
@ -0,0 +1,196 @@
|
||||
// ## Tag Selector UI
|
||||
|
||||
/*jslint regexp: true */ // - would like to remove this
|
||||
/*global jQuery, document, window */
|
||||
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
var suggestions,
|
||||
categoryOffset,
|
||||
existingTags = [ // This will be replaced by an API return.
|
||||
'quim',
|
||||
'quimtastic',
|
||||
'quimmy',
|
||||
'quimlord',
|
||||
'quickly',
|
||||
'joaquim pheonix',
|
||||
'quimcy jones'
|
||||
],
|
||||
keys = {
|
||||
UP: 38,
|
||||
DOWN: 40,
|
||||
ESC: 27,
|
||||
ENTER: 13,
|
||||
COMMA: 188,
|
||||
BACKSPACE: 8
|
||||
};
|
||||
|
||||
function findTerms(searchTerm, array) {
|
||||
searchTerm = searchTerm.toUpperCase();
|
||||
return $.map(array, function (item) {
|
||||
var match = item.toUpperCase().indexOf(searchTerm) !== -1;
|
||||
return match ? item : null;
|
||||
});
|
||||
}
|
||||
|
||||
function showSuggestions($target, searchTerm) {
|
||||
suggestions.show();
|
||||
var results = findTerms(searchTerm, existingTags),
|
||||
pos = $target.position(),
|
||||
styles = {
|
||||
left: pos.left
|
||||
},
|
||||
maxSuggestions = 5, // Limit the suggestions number
|
||||
results_length = results.length,
|
||||
i,
|
||||
suggest;
|
||||
|
||||
suggestions.css(styles);
|
||||
suggestions.html("");
|
||||
|
||||
if (results_length < maxSuggestions) {
|
||||
maxSuggestions = results_length;
|
||||
}
|
||||
for (i = 0; i < maxSuggestions; i += 1) {
|
||||
suggestions.append("<li><a href='#'>" + results[i] + "</a></li>");
|
||||
}
|
||||
|
||||
suggest = $('ul.suggestions li a:contains("' + searchTerm + '")');
|
||||
|
||||
suggest.each(function () {
|
||||
var src_str = $(this).html(),
|
||||
term = searchTerm,
|
||||
pattern;
|
||||
|
||||
term = term.replace(/(\s+)/, "(<[^>]+>)*$1(<[^>]+>)*");
|
||||
pattern = new RegExp("(" + term + ")", "i");
|
||||
|
||||
src_str = src_str.replace(pattern, "<mark>$1</mark>");
|
||||
src_str = src_str.replace(/(<mark>[^<>]*)((<[^>]+>)+)([^<>]*<\/mark>)/, "$1</mark>$2<mark>$4");
|
||||
|
||||
$(this).html(src_str);
|
||||
});
|
||||
}
|
||||
|
||||
function handleTagKeyup(e) {
|
||||
var $target = $(e.currentTarget),
|
||||
searchTerm = $.trim($target.val()).toLowerCase(),
|
||||
category,
|
||||
populator;
|
||||
|
||||
if (e.keyCode === keys.UP) {
|
||||
e.preventDefault();
|
||||
if (suggestions.is(":visible")) {
|
||||
if (suggestions.children(".selected").length === 0) {
|
||||
suggestions.find("li:last-child").addClass('selected');
|
||||
} else {
|
||||
suggestions.children(".selected").removeClass('selected').prev().addClass('selected');
|
||||
}
|
||||
}
|
||||
} else if (e.keyCode === keys.DOWN) {
|
||||
e.preventDefault();
|
||||
if (suggestions.is(":visible")) {
|
||||
if (suggestions.children(".selected").length === 0) {
|
||||
suggestions.find("li:first-child").addClass('selected');
|
||||
} else {
|
||||
suggestions.children(".selected").removeClass('selected').next().addClass('selected');
|
||||
}
|
||||
}
|
||||
} else if (e.keyCode === keys.ESC) {
|
||||
suggestions.hide();
|
||||
} else if ((e.keyCode === keys.ENTER || e.keyCode === keys.COMMA)
|
||||
&& searchTerm) { // Submit tag using enter or comma key
|
||||
e.preventDefault();
|
||||
if (suggestions.is(":visible") && suggestions.children(".selected").length !== 0) {
|
||||
|
||||
if ($('.category:containsExact("' + suggestions.children(".selected").text() + '")').length === 0) {
|
||||
|
||||
category = $('<span class="category">' + suggestions.children(".selected").text() + '</span>');
|
||||
if ($target.data('populate')) {
|
||||
|
||||
populator = $($target.data('populate'));
|
||||
populator.append(category);
|
||||
}
|
||||
}
|
||||
suggestions.hide();
|
||||
} else {
|
||||
if (e.keyCode === keys.COMMA) {
|
||||
searchTerm = searchTerm.replace(",", "");
|
||||
} // Remove comma from string if comma is uses to submit.
|
||||
if ($('.category:containsExact("' + searchTerm + '")').length === 0) {
|
||||
category = $('<span class="category">' + searchTerm + '</span>');
|
||||
if ($target.data('populate')) {
|
||||
populator = $($target.data('populate'));
|
||||
populator.append(category);
|
||||
}
|
||||
}
|
||||
}
|
||||
$target.val('').focus();
|
||||
searchTerm = ""; // Used to reset search term
|
||||
suggestions.hide();
|
||||
}
|
||||
|
||||
if (e.keyCode === keys.UP || e.keyCode === keys.DOWN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (searchTerm) {
|
||||
showSuggestions($target, searchTerm);
|
||||
} else {
|
||||
suggestions.hide();
|
||||
}
|
||||
}
|
||||
|
||||
function handleTagKeyDown(e) {
|
||||
var $target = $(e.currentTarget),
|
||||
populator,
|
||||
lastBlock;
|
||||
// Delete character tiggers on Keydown, so needed to check on that event rather than Keyup.
|
||||
if (e.keyCode === keys.BACKSPACE && !$target.val()) {
|
||||
populator = $($target.data('populate'));
|
||||
lastBlock = populator.find('.category').last();
|
||||
lastBlock.remove();
|
||||
}
|
||||
}
|
||||
|
||||
function handleSuggestionClick(e) {
|
||||
var $target = $(e.currentTarget),
|
||||
category = $('<span class="category">' + $(e.currentTarget).text() + '</span>'),
|
||||
populator;
|
||||
|
||||
if ($target.parent().data('populate')) {
|
||||
populator = $($target.parent().data('populate'));
|
||||
populator.append(category);
|
||||
suggestions.hide();
|
||||
$('[data-input-behaviour="tag"]').val('').focus();
|
||||
}
|
||||
}
|
||||
|
||||
function handleCategoryClick(e) {
|
||||
$(e.currentTarget).remove();
|
||||
}
|
||||
|
||||
function handleClickOff(e) {
|
||||
if (window.matchMedia('max-width: 650px')) {
|
||||
e.preventDefault();
|
||||
$('body').toggleClass('off-canvas');
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
suggestions = $("ul.suggestions").hide(); // Initnialise suggestions overlay
|
||||
|
||||
if ($('.category-input').length) {
|
||||
categoryOffset = $('.category-input').offset().left;
|
||||
$('.category-blocks').css({'left': categoryOffset + 'px'});
|
||||
}
|
||||
|
||||
$('[data-input-behaviour="tag"]')
|
||||
.on('keyup', handleTagKeyup)
|
||||
.on('keydown', handleTagKeyDown);
|
||||
$('ul.suggestions').on('click', "li", handleSuggestionClick);
|
||||
$('.categories').on('click', ".category", handleCategoryClick);
|
||||
$('[data-off-canvas]').on('click', handleClickOff);
|
||||
});
|
||||
}(jQuery));
|
30
core/admin/assets/js/toggle.js
Normal file
@ -0,0 +1,30 @@
|
||||
// # Toggle Support
|
||||
|
||||
/*global document, jQuery */
|
||||
(function ($) {
|
||||
"use strict";
|
||||
$(document).ready(function () {
|
||||
|
||||
// ## Toggle Up In Your Grill
|
||||
// Allows for toggling via data-attributes.
|
||||
// ### Usage
|
||||
// <nav>
|
||||
// <a href="#" data-toggle=".toggle-me">Toggle</a>
|
||||
// <ul class="toggle-me">
|
||||
// <li>Toggled yo</li>
|
||||
// </ul>
|
||||
// </nav>
|
||||
$('[data-toggle]').each(function () {
|
||||
var toggle = $(this).data('toggle');
|
||||
$(this).parent().children(toggle).hide();
|
||||
});
|
||||
|
||||
$('[data-toggle]').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
$(this).toggleClass('active');
|
||||
var toggle = $(this).data('toggle');
|
||||
$(this).parent().children(toggle).fadeToggle(100).toggleClass('open');
|
||||
});
|
||||
|
||||
});
|
||||
}(jQuery));
|
39
core/admin/assets/lib/chart.min.js
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
var Chart=function(s){function v(a,c,b){a=A((a-c.graphMin)/(c.steps*c.stepValue),1,0);return b*c.steps*a}function x(a,c,b,e){function h(){g+=f;var k=a.animation?A(d(g),null,0):1;e.clearRect(0,0,q,u);a.scaleOverlay?(b(k),c()):(c(),b(k));if(1>=g)D(h);else if("function"==typeof a.onAnimationComplete)a.onAnimationComplete()}var f=a.animation?1/A(a.animationSteps,Number.MAX_VALUE,1):1,d=B[a.animationEasing],g=a.animation?0:1;"function"!==typeof c&&(c=function(){});D(h)}function C(a,c,b,e,h,f){var d;a=
|
||||
Math.floor(Math.log(e-h)/Math.LN10);h=Math.floor(h/(1*Math.pow(10,a)))*Math.pow(10,a);e=Math.ceil(e/(1*Math.pow(10,a)))*Math.pow(10,a)-h;a=Math.pow(10,a);for(d=Math.round(e/a);d<b||d>c;)a=d<b?a/2:2*a,d=Math.round(e/a);c=[];z(f,c,d,h,a);return{steps:d,stepValue:a,graphMin:h,labels:c}}function z(a,c,b,e,h){if(a)for(var f=1;f<b+1;f++)c.push(E(a,{value:(e+h*f).toFixed(0!=h%1?h.toString().split(".")[1].length:0)}))}function A(a,c,b){return!isNaN(parseFloat(c))&&isFinite(c)&&a>c?c:!isNaN(parseFloat(b))&&
|
||||
isFinite(b)&&a<b?b:a}function y(a,c){var b={},e;for(e in a)b[e]=a[e];for(e in c)b[e]=c[e];return b}function E(a,c){var b=!/\W/.test(a)?F[a]=F[a]||E(document.getElementById(a).innerHTML):new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.replace(/[\r\t\n]/g," ").split("<%").join("\t").replace(/((^|%>)[^\t]*)'/g,"$1\r").replace(/\t=(.*?)%>/g,"',$1,'").split("\t").join("');").split("%>").join("p.push('").split("\r").join("\\'")+"');}return p.join('');");return c?
|
||||
b(c):b}var r=this,B={linear:function(a){return a},easeInQuad:function(a){return a*a},easeOutQuad:function(a){return-1*a*(a-2)},easeInOutQuad:function(a){return 1>(a/=0.5)?0.5*a*a:-0.5*(--a*(a-2)-1)},easeInCubic:function(a){return a*a*a},easeOutCubic:function(a){return 1*((a=a/1-1)*a*a+1)},easeInOutCubic:function(a){return 1>(a/=0.5)?0.5*a*a*a:0.5*((a-=2)*a*a+2)},easeInQuart:function(a){return a*a*a*a},easeOutQuart:function(a){return-1*((a=a/1-1)*a*a*a-1)},easeInOutQuart:function(a){return 1>(a/=0.5)?
|
||||
0.5*a*a*a*a:-0.5*((a-=2)*a*a*a-2)},easeInQuint:function(a){return 1*(a/=1)*a*a*a*a},easeOutQuint:function(a){return 1*((a=a/1-1)*a*a*a*a+1)},easeInOutQuint:function(a){return 1>(a/=0.5)?0.5*a*a*a*a*a:0.5*((a-=2)*a*a*a*a+2)},easeInSine:function(a){return-1*Math.cos(a/1*(Math.PI/2))+1},easeOutSine:function(a){return 1*Math.sin(a/1*(Math.PI/2))},easeInOutSine:function(a){return-0.5*(Math.cos(Math.PI*a/1)-1)},easeInExpo:function(a){return 0==a?1:1*Math.pow(2,10*(a/1-1))},easeOutExpo:function(a){return 1==
|
||||
a?1:1*(-Math.pow(2,-10*a/1)+1)},easeInOutExpo:function(a){return 0==a?0:1==a?1:1>(a/=0.5)?0.5*Math.pow(2,10*(a-1)):0.5*(-Math.pow(2,-10*--a)+2)},easeInCirc:function(a){return 1<=a?a:-1*(Math.sqrt(1-(a/=1)*a)-1)},easeOutCirc:function(a){return 1*Math.sqrt(1-(a=a/1-1)*a)},easeInOutCirc:function(a){return 1>(a/=0.5)?-0.5*(Math.sqrt(1-a*a)-1):0.5*(Math.sqrt(1-(a-=2)*a)+1)},easeInElastic:function(a){var c=1.70158,b=0,e=1;if(0==a)return 0;if(1==(a/=1))return 1;b||(b=0.3);e<Math.abs(1)?(e=1,c=b/4):c=b/(2*
|
||||
Math.PI)*Math.asin(1/e);return-(e*Math.pow(2,10*(a-=1))*Math.sin((1*a-c)*2*Math.PI/b))},easeOutElastic:function(a){var c=1.70158,b=0,e=1;if(0==a)return 0;if(1==(a/=1))return 1;b||(b=0.3);e<Math.abs(1)?(e=1,c=b/4):c=b/(2*Math.PI)*Math.asin(1/e);return e*Math.pow(2,-10*a)*Math.sin((1*a-c)*2*Math.PI/b)+1},easeInOutElastic:function(a){var c=1.70158,b=0,e=1;if(0==a)return 0;if(2==(a/=0.5))return 1;b||(b=1*0.3*1.5);e<Math.abs(1)?(e=1,c=b/4):c=b/(2*Math.PI)*Math.asin(1/e);return 1>a?-0.5*e*Math.pow(2,10*
|
||||
(a-=1))*Math.sin((1*a-c)*2*Math.PI/b):0.5*e*Math.pow(2,-10*(a-=1))*Math.sin((1*a-c)*2*Math.PI/b)+1},easeInBack:function(a){return 1*(a/=1)*a*(2.70158*a-1.70158)},easeOutBack:function(a){return 1*((a=a/1-1)*a*(2.70158*a+1.70158)+1)},easeInOutBack:function(a){var c=1.70158;return 1>(a/=0.5)?0.5*a*a*(((c*=1.525)+1)*a-c):0.5*((a-=2)*a*(((c*=1.525)+1)*a+c)+2)},easeInBounce:function(a){return 1-B.easeOutBounce(1-a)},easeOutBounce:function(a){return(a/=1)<1/2.75?1*7.5625*a*a:a<2/2.75?1*(7.5625*(a-=1.5/2.75)*
|
||||
a+0.75):a<2.5/2.75?1*(7.5625*(a-=2.25/2.75)*a+0.9375):1*(7.5625*(a-=2.625/2.75)*a+0.984375)},easeInOutBounce:function(a){return 0.5>a?0.5*B.easeInBounce(2*a):0.5*B.easeOutBounce(2*a-1)+0.5}},q=s.canvas.width,u=s.canvas.height;window.devicePixelRatio&&(s.canvas.style.width=q+"px",s.canvas.style.height=u+"px",s.canvas.height=u*window.devicePixelRatio,s.canvas.width=q*window.devicePixelRatio,s.scale(window.devicePixelRatio,window.devicePixelRatio));this.PolarArea=function(a,c){r.PolarArea.defaults={scaleOverlay:!0,
|
||||
scaleOverride:!1,scaleSteps:null,scaleStepWidth:null,scaleStartValue:null,scaleShowLine:!0,scaleLineColor:"rgba(0,0,0,.1)",scaleLineWidth:1,scaleShowLabels:!0,scaleLabel:"<%=value%>",scaleFontFamily:"'Arial'",scaleFontSize:12,scaleFontStyle:"normal",scaleFontColor:"#666",scaleShowLabelBackdrop:!0,scaleBackdropColor:"rgba(255,255,255,0.75)",scaleBackdropPaddingY:2,scaleBackdropPaddingX:2,segmentShowStroke:!0,segmentStrokeColor:"#fff",segmentStrokeWidth:2,animation:!0,animationSteps:100,animationEasing:"easeOutBounce",
|
||||
animateRotate:!0,animateScale:!1,onAnimationComplete:null};var b=c?y(r.PolarArea.defaults,c):r.PolarArea.defaults;return new G(a,b,s)};this.Radar=function(a,c){r.Radar.defaults={scaleOverlay:!1,scaleOverride:!1,scaleSteps:null,scaleStepWidth:null,scaleStartValue:null,scaleShowLine:!0,scaleLineColor:"rgba(0,0,0,.1)",scaleLineWidth:1,scaleShowLabels:!1,scaleLabel:"<%=value%>",scaleFontFamily:"'Arial'",scaleFontSize:12,scaleFontStyle:"normal",scaleFontColor:"#666",scaleShowLabelBackdrop:!0,scaleBackdropColor:"rgba(255,255,255,0.75)",
|
||||
scaleBackdropPaddingY:2,scaleBackdropPaddingX:2,angleShowLineOut:!0,angleLineColor:"rgba(0,0,0,.1)",angleLineWidth:1,pointLabelFontFamily:"'Arial'",pointLabelFontStyle:"normal",pointLabelFontSize:12,pointLabelFontColor:"#666",pointDot:!0,pointDotRadius:3,pointDotStrokeWidth:1,datasetStroke:!0,datasetStrokeWidth:2,datasetFill:!0,animation:!0,animationSteps:60,animationEasing:"easeOutQuart",onAnimationComplete:null};var b=c?y(r.Radar.defaults,c):r.Radar.defaults;return new H(a,b,s)};this.Pie=function(a,
|
||||
c){r.Pie.defaults={segmentShowStroke:!0,segmentStrokeColor:"#fff",segmentStrokeWidth:2,animation:!0,animationSteps:100,animationEasing:"easeOutBounce",animateRotate:!0,animateScale:!1,onAnimationComplete:null};var b=c?y(r.Pie.defaults,c):r.Pie.defaults;return new I(a,b,s)};this.Doughnut=function(a,c){r.Doughnut.defaults={segmentShowStroke:!0,segmentStrokeColor:"#fff",segmentStrokeWidth:2,percentageInnerCutout:50,animation:!0,animationSteps:100,animationEasing:"easeOutBounce",animateRotate:!0,animateScale:!1,
|
||||
onAnimationComplete:null};var b=c?y(r.Doughnut.defaults,c):r.Doughnut.defaults;return new J(a,b,s)};this.Line=function(a,c){r.Line.defaults={scaleOverlay:!1,scaleOverride:!1,scaleSteps:null,scaleStepWidth:null,scaleStartValue:null,scaleLineColor:"rgba(0,0,0,.1)",scaleLineWidth:1,scaleShowLabels:!0,scaleLabel:"<%=value%>",scaleFontFamily:"'Arial'",scaleFontSize:12,scaleFontStyle:"normal",scaleFontColor:"#666",scaleShowGridLines:!0,scaleGridLineColor:"rgba(0,0,0,.05)",scaleGridLineWidth:1,bezierCurve:!0,
|
||||
pointDot:!0,pointDotRadius:4,pointDotStrokeWidth:2,datasetStroke:!0,datasetStrokeWidth:2,datasetFill:!0,animation:!0,animationSteps:60,animationEasing:"easeOutQuart",onAnimationComplete:null};var b=c?y(r.Line.defaults,c):r.Line.defaults;return new K(a,b,s)};this.Bar=function(a,c){r.Bar.defaults={scaleOverlay:!1,scaleOverride:!1,scaleSteps:null,scaleStepWidth:null,scaleStartValue:null,scaleLineColor:"rgba(0,0,0,.1)",scaleLineWidth:1,scaleShowLabels:!0,scaleLabel:"<%=value%>",scaleFontFamily:"'Arial'",
|
||||
scaleFontSize:12,scaleFontStyle:"normal",scaleFontColor:"#666",scaleShowGridLines:!0,scaleGridLineColor:"rgba(0,0,0,.05)",scaleGridLineWidth:1,barShowStroke:!0,barStrokeWidth:2,barValueSpacing:5,barDatasetSpacing:1,animation:!0,animationSteps:60,animationEasing:"easeOutQuart",onAnimationComplete:null};var b=c?y(r.Bar.defaults,c):r.Bar.defaults;return new L(a,b,s)};var G=function(a,c,b){var e,h,f,d,g,k,j,l,m;g=Math.min.apply(Math,[q,u])/2;g-=Math.max.apply(Math,[0.5*c.scaleFontSize,0.5*c.scaleLineWidth]);
|
||||
d=2*c.scaleFontSize;c.scaleShowLabelBackdrop&&(d+=2*c.scaleBackdropPaddingY,g-=1.5*c.scaleBackdropPaddingY);l=g;d=d?d:5;e=Number.MIN_VALUE;h=Number.MAX_VALUE;for(f=0;f<a.length;f++)a[f].value>e&&(e=a[f].value),a[f].value<h&&(h=a[f].value);f=Math.floor(l/(0.66*d));d=Math.floor(0.5*(l/d));m=c.scaleShowLabels?c.scaleLabel:null;c.scaleOverride?(j={steps:c.scaleSteps,stepValue:c.scaleStepWidth,graphMin:c.scaleStartValue,labels:[]},z(m,j.labels,j.steps,c.scaleStartValue,c.scaleStepWidth)):j=C(l,f,d,e,h,
|
||||
m);k=g/j.steps;x(c,function(){for(var a=0;a<j.steps;a++)if(c.scaleShowLine&&(b.beginPath(),b.arc(q/2,u/2,k*(a+1),0,2*Math.PI,!0),b.strokeStyle=c.scaleLineColor,b.lineWidth=c.scaleLineWidth,b.stroke()),c.scaleShowLabels){b.textAlign="center";b.font=c.scaleFontStyle+" "+c.scaleFontSize+"px "+c.scaleFontFamily;var e=j.labels[a];if(c.scaleShowLabelBackdrop){var d=b.measureText(e).width;b.fillStyle=c.scaleBackdropColor;b.beginPath();b.rect(Math.round(q/2-d/2-c.scaleBackdropPaddingX),Math.round(u/2-k*(a+
|
||||
1)-0.5*c.scaleFontSize-c.scaleBackdropPaddingY),Math.round(d+2*c.scaleBackdropPaddingX),Math.round(c.scaleFontSize+2*c.scaleBackdropPaddingY));b.fill()}b.textBaseline="middle";b.fillStyle=c.scaleFontColor;b.fillText(e,q/2,u/2-k*(a+1))}},function(e){var d=-Math.PI/2,g=2*Math.PI/a.length,f=1,h=1;c.animation&&(c.animateScale&&(f=e),c.animateRotate&&(h=e));for(e=0;e<a.length;e++)b.beginPath(),b.arc(q/2,u/2,f*v(a[e].value,j,k),d,d+h*g,!1),b.lineTo(q/2,u/2),b.closePath(),b.fillStyle=a[e].color,b.fill(),
|
||||
c.segmentShowStroke&&(b.strokeStyle=c.segmentStrokeColor,b.lineWidth=c.segmentStrokeWidth,b.stroke()),d+=h*g},b)},H=function(a,c,b){var e,h,f,d,g,k,j,l,m;a.labels||(a.labels=[]);g=Math.min.apply(Math,[q,u])/2;d=2*c.scaleFontSize;for(e=l=0;e<a.labels.length;e++)b.font=c.pointLabelFontStyle+" "+c.pointLabelFontSize+"px "+c.pointLabelFontFamily,h=b.measureText(a.labels[e]).width,h>l&&(l=h);g-=Math.max.apply(Math,[l,1.5*(c.pointLabelFontSize/2)]);g-=c.pointLabelFontSize;l=g=A(g,null,0);d=d?d:5;e=Number.MIN_VALUE;
|
||||
h=Number.MAX_VALUE;for(f=0;f<a.datasets.length;f++)for(m=0;m<a.datasets[f].data.length;m++)a.datasets[f].data[m]>e&&(e=a.datasets[f].data[m]),a.datasets[f].data[m]<h&&(h=a.datasets[f].data[m]);f=Math.floor(l/(0.66*d));d=Math.floor(0.5*(l/d));m=c.scaleShowLabels?c.scaleLabel:null;c.scaleOverride?(j={steps:c.scaleSteps,stepValue:c.scaleStepWidth,graphMin:c.scaleStartValue,labels:[]},z(m,j.labels,j.steps,c.scaleStartValue,c.scaleStepWidth)):j=C(l,f,d,e,h,m);k=g/j.steps;x(c,function(){var e=2*Math.PI/
|
||||
a.datasets[0].data.length;b.save();b.translate(q/2,u/2);if(c.angleShowLineOut){b.strokeStyle=c.angleLineColor;b.lineWidth=c.angleLineWidth;for(var d=0;d<a.datasets[0].data.length;d++)b.rotate(e),b.beginPath(),b.moveTo(0,0),b.lineTo(0,-g),b.stroke()}for(d=0;d<j.steps;d++){b.beginPath();if(c.scaleShowLine){b.strokeStyle=c.scaleLineColor;b.lineWidth=c.scaleLineWidth;b.moveTo(0,-k*(d+1));for(var f=0;f<a.datasets[0].data.length;f++)b.rotate(e),b.lineTo(0,-k*(d+1));b.closePath();b.stroke()}c.scaleShowLabels&&
|
||||
(b.textAlign="center",b.font=c.scaleFontStyle+" "+c.scaleFontSize+"px "+c.scaleFontFamily,b.textBaseline="middle",c.scaleShowLabelBackdrop&&(f=b.measureText(j.labels[d]).width,b.fillStyle=c.scaleBackdropColor,b.beginPath(),b.rect(Math.round(-f/2-c.scaleBackdropPaddingX),Math.round(-k*(d+1)-0.5*c.scaleFontSize-c.scaleBackdropPaddingY),Math.round(f+2*c.scaleBackdropPaddingX),Math.round(c.scaleFontSize+2*c.scaleBackdropPaddingY)),b.fill()),b.fillStyle=c.scaleFontColor,b.fillText(j.labels[d],0,-k*(d+
|
||||
1)))}for(d=0;d<a.labels.length;d++){b.font=c.pointLabelFontStyle+" "+c.pointLabelFontSize+"px "+c.pointLabelFontFamily;b.fillStyle=c.pointLabelFontColor;var f=Math.sin(e*d)*(g+c.pointLabelFontSize),h=Math.cos(e*d)*(g+c.pointLabelFontSize);b.textAlign=e*d==Math.PI||0==e*d?"center":e*d>Math.PI?"right":"left";b.textBaseline="middle";b.fillText(a.labels[d],f,-h)}b.restore()},function(d){var e=2*Math.PI/a.datasets[0].data.length;b.save();b.translate(q/2,u/2);for(var g=0;g<a.datasets.length;g++){b.beginPath();
|
||||
b.moveTo(0,d*-1*v(a.datasets[g].data[0],j,k));for(var f=1;f<a.datasets[g].data.length;f++)b.rotate(e),b.lineTo(0,d*-1*v(a.datasets[g].data[f],j,k));b.closePath();b.fillStyle=a.datasets[g].fillColor;b.strokeStyle=a.datasets[g].strokeColor;b.lineWidth=c.datasetStrokeWidth;b.fill();b.stroke();if(c.pointDot){b.fillStyle=a.datasets[g].pointColor;b.strokeStyle=a.datasets[g].pointStrokeColor;b.lineWidth=c.pointDotStrokeWidth;for(f=0;f<a.datasets[g].data.length;f++)b.rotate(e),b.beginPath(),b.arc(0,d*-1*
|
||||
v(a.datasets[g].data[f],j,k),c.pointDotRadius,2*Math.PI,!1),b.fill(),b.stroke()}b.rotate(e)}b.restore()},b)},I=function(a,c,b){for(var e=0,h=Math.min.apply(Math,[u/2,q/2])-5,f=0;f<a.length;f++)e+=a[f].value;x(c,null,function(d){var g=-Math.PI/2,f=1,j=1;c.animation&&(c.animateScale&&(f=d),c.animateRotate&&(j=d));for(d=0;d<a.length;d++){var l=j*a[d].value/e*2*Math.PI;b.beginPath();b.arc(q/2,u/2,f*h,g,g+l);b.lineTo(q/2,u/2);b.closePath();b.fillStyle=a[d].color;b.fill();c.segmentShowStroke&&(b.lineWidth=
|
||||
c.segmentStrokeWidth,b.strokeStyle=c.segmentStrokeColor,b.stroke());g+=l}},b)},J=function(a,c,b){for(var e=0,h=Math.min.apply(Math,[u/2,q/2])-5,f=h*(c.percentageInnerCutout/100),d=0;d<a.length;d++)e+=a[d].value;x(c,null,function(d){var k=-Math.PI/2,j=1,l=1;c.animation&&(c.animateScale&&(j=d),c.animateRotate&&(l=d));for(d=0;d<a.length;d++){var m=l*a[d].value/e*2*Math.PI;b.beginPath();b.arc(q/2,u/2,j*h,k,k+m,!1);b.arc(q/2,u/2,j*f,k+m,k,!0);b.closePath();b.fillStyle=a[d].color;b.fill();c.segmentShowStroke&&
|
||||
(b.lineWidth=c.segmentStrokeWidth,b.strokeStyle=c.segmentStrokeColor,b.stroke());k+=m}},b)},K=function(a,c,b){var e,h,f,d,g,k,j,l,m,t,r,n,p,s=0;g=u;b.font=c.scaleFontStyle+" "+c.scaleFontSize+"px "+c.scaleFontFamily;t=1;for(d=0;d<a.labels.length;d++)e=b.measureText(a.labels[d]).width,t=e>t?e:t;q/a.labels.length<t?(s=45,q/a.labels.length<Math.cos(s)*t?(s=90,g-=t):g-=Math.sin(s)*t):g-=c.scaleFontSize;d=c.scaleFontSize;g=g-5-d;e=Number.MIN_VALUE;h=Number.MAX_VALUE;for(f=0;f<a.datasets.length;f++)for(l=
|
||||
0;l<a.datasets[f].data.length;l++)a.datasets[f].data[l]>e&&(e=a.datasets[f].data[l]),a.datasets[f].data[l]<h&&(h=a.datasets[f].data[l]);f=Math.floor(g/(0.66*d));d=Math.floor(0.5*(g/d));l=c.scaleShowLabels?c.scaleLabel:"";c.scaleOverride?(j={steps:c.scaleSteps,stepValue:c.scaleStepWidth,graphMin:c.scaleStartValue,labels:[]},z(l,j.labels,j.steps,c.scaleStartValue,c.scaleStepWidth)):j=C(g,f,d,e,h,l);k=Math.floor(g/j.steps);d=1;if(c.scaleShowLabels){b.font=c.scaleFontStyle+" "+c.scaleFontSize+"px "+c.scaleFontFamily;
|
||||
for(e=0;e<j.labels.length;e++)h=b.measureText(j.labels[e]).width,d=h>d?h:d;d+=10}r=q-d-t;m=Math.floor(r/(a.labels.length-1));n=q-t/2-r;p=g+c.scaleFontSize/2;x(c,function(){b.lineWidth=c.scaleLineWidth;b.strokeStyle=c.scaleLineColor;b.beginPath();b.moveTo(q-t/2+5,p);b.lineTo(q-t/2-r-5,p);b.stroke();0<s?(b.save(),b.textAlign="right"):b.textAlign="center";b.fillStyle=c.scaleFontColor;for(var d=0;d<a.labels.length;d++)b.save(),0<s?(b.translate(n+d*m,p+c.scaleFontSize),b.rotate(-(s*(Math.PI/180))),b.fillText(a.labels[d],
|
||||
0,0),b.restore()):b.fillText(a.labels[d],n+d*m,p+c.scaleFontSize+3),b.beginPath(),b.moveTo(n+d*m,p+3),c.scaleShowGridLines&&0<d?(b.lineWidth=c.scaleGridLineWidth,b.strokeStyle=c.scaleGridLineColor,b.lineTo(n+d*m,5)):b.lineTo(n+d*m,p+3),b.stroke();b.lineWidth=c.scaleLineWidth;b.strokeStyle=c.scaleLineColor;b.beginPath();b.moveTo(n,p+5);b.lineTo(n,5);b.stroke();b.textAlign="right";b.textBaseline="middle";for(d=0;d<j.steps;d++)b.beginPath(),b.moveTo(n-3,p-(d+1)*k),c.scaleShowGridLines?(b.lineWidth=c.scaleGridLineWidth,
|
||||
b.strokeStyle=c.scaleGridLineColor,b.lineTo(n+r+5,p-(d+1)*k)):b.lineTo(n-0.5,p-(d+1)*k),b.stroke(),c.scaleShowLabels&&b.fillText(j.labels[d],n-8,p-(d+1)*k)},function(d){function e(b,c){return p-d*v(a.datasets[b].data[c],j,k)}for(var f=0;f<a.datasets.length;f++){b.strokeStyle=a.datasets[f].strokeColor;b.lineWidth=c.datasetStrokeWidth;b.beginPath();b.moveTo(n,p-d*v(a.datasets[f].data[0],j,k));for(var g=1;g<a.datasets[f].data.length;g++)c.bezierCurve?b.bezierCurveTo(n+m*(g-0.5),e(f,g-1),n+m*(g-0.5),
|
||||
e(f,g),n+m*g,e(f,g)):b.lineTo(n+m*g,e(f,g));b.stroke();c.datasetFill?(b.lineTo(n+m*(a.datasets[f].data.length-1),p),b.lineTo(n,p),b.closePath(),b.fillStyle=a.datasets[f].fillColor,b.fill()):b.closePath();if(c.pointDot){b.fillStyle=a.datasets[f].pointColor;b.strokeStyle=a.datasets[f].pointStrokeColor;b.lineWidth=c.pointDotStrokeWidth;for(g=0;g<a.datasets[f].data.length;g++)b.beginPath(),b.arc(n+m*g,p-d*v(a.datasets[f].data[g],j,k),c.pointDotRadius,0,2*Math.PI,!0),b.fill(),b.stroke()}}},b)},L=function(a,
|
||||
c,b){var e,h,f,d,g,k,j,l,m,t,r,n,p,s,w=0;g=u;b.font=c.scaleFontStyle+" "+c.scaleFontSize+"px "+c.scaleFontFamily;t=1;for(d=0;d<a.labels.length;d++)e=b.measureText(a.labels[d]).width,t=e>t?e:t;q/a.labels.length<t?(w=45,q/a.labels.length<Math.cos(w)*t?(w=90,g-=t):g-=Math.sin(w)*t):g-=c.scaleFontSize;d=c.scaleFontSize;g=g-5-d;e=Number.MIN_VALUE;h=Number.MAX_VALUE;for(f=0;f<a.datasets.length;f++)for(l=0;l<a.datasets[f].data.length;l++)a.datasets[f].data[l]>e&&(e=a.datasets[f].data[l]),a.datasets[f].data[l]<
|
||||
h&&(h=a.datasets[f].data[l]);f=Math.floor(g/(0.66*d));d=Math.floor(0.5*(g/d));l=c.scaleShowLabels?c.scaleLabel:"";c.scaleOverride?(j={steps:c.scaleSteps,stepValue:c.scaleStepWidth,graphMin:c.scaleStartValue,labels:[]},z(l,j.labels,j.steps,c.scaleStartValue,c.scaleStepWidth)):j=C(g,f,d,e,h,l);k=Math.floor(g/j.steps);d=1;if(c.scaleShowLabels){b.font=c.scaleFontStyle+" "+c.scaleFontSize+"px "+c.scaleFontFamily;for(e=0;e<j.labels.length;e++)h=b.measureText(j.labels[e]).width,d=h>d?h:d;d+=10}r=q-d-t;m=
|
||||
Math.floor(r/a.labels.length);s=(m-2*c.scaleGridLineWidth-2*c.barValueSpacing-(c.barDatasetSpacing*a.datasets.length-1)-(c.barStrokeWidth/2*a.datasets.length-1))/a.datasets.length;n=q-t/2-r;p=g+c.scaleFontSize/2;x(c,function(){b.lineWidth=c.scaleLineWidth;b.strokeStyle=c.scaleLineColor;b.beginPath();b.moveTo(q-t/2+5,p);b.lineTo(q-t/2-r-5,p);b.stroke();0<w?(b.save(),b.textAlign="right"):b.textAlign="center";b.fillStyle=c.scaleFontColor;for(var d=0;d<a.labels.length;d++)b.save(),0<w?(b.translate(n+
|
||||
d*m,p+c.scaleFontSize),b.rotate(-(w*(Math.PI/180))),b.fillText(a.labels[d],0,0),b.restore()):b.fillText(a.labels[d],n+d*m+m/2,p+c.scaleFontSize+3),b.beginPath(),b.moveTo(n+(d+1)*m,p+3),b.lineWidth=c.scaleGridLineWidth,b.strokeStyle=c.scaleGridLineColor,b.lineTo(n+(d+1)*m,5),b.stroke();b.lineWidth=c.scaleLineWidth;b.strokeStyle=c.scaleLineColor;b.beginPath();b.moveTo(n,p+5);b.lineTo(n,5);b.stroke();b.textAlign="right";b.textBaseline="middle";for(d=0;d<j.steps;d++)b.beginPath(),b.moveTo(n-3,p-(d+1)*
|
||||
k),c.scaleShowGridLines?(b.lineWidth=c.scaleGridLineWidth,b.strokeStyle=c.scaleGridLineColor,b.lineTo(n+r+5,p-(d+1)*k)):b.lineTo(n-0.5,p-(d+1)*k),b.stroke(),c.scaleShowLabels&&b.fillText(j.labels[d],n-8,p-(d+1)*k)},function(d){b.lineWidth=c.barStrokeWidth;for(var e=0;e<a.datasets.length;e++){b.fillStyle=a.datasets[e].fillColor;b.strokeStyle=a.datasets[e].strokeColor;for(var f=0;f<a.datasets[e].data.length;f++){var g=n+c.barValueSpacing+m*f+s*e+c.barDatasetSpacing*e+c.barStrokeWidth*e;b.beginPath();
|
||||
b.moveTo(g,p);b.lineTo(g,p-d*v(a.datasets[e].data[f],j,k)+c.barStrokeWidth/2);b.lineTo(g+s,p-d*v(a.datasets[e].data[f],j,k)+c.barStrokeWidth/2);b.lineTo(g+s,p);c.barShowStroke&&b.stroke();b.closePath();b.fill()}}},b)},D=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){window.setTimeout(a,1E3/60)},F={}};
|
246
core/admin/assets/lib/codemirror/codemirror.css
Normal file
@ -0,0 +1,246 @@
|
||||
/* BASICS */
|
||||
|
||||
.CodeMirror {
|
||||
/* Set height, width, borders, and global font properties here */
|
||||
font-family: monospace;
|
||||
height: 300px;
|
||||
}
|
||||
.CodeMirror-scroll {
|
||||
/* Set scrolling behaviour here */
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* PADDING */
|
||||
|
||||
.CodeMirror-lines {
|
||||
padding: 4px 0; /* Vertical padding around content */
|
||||
}
|
||||
.CodeMirror pre {
|
||||
padding: 0 4px; /* Horizontal padding of content */
|
||||
}
|
||||
|
||||
.CodeMirror-scrollbar-filler {
|
||||
background-color: white; /* The little square between H and V scrollbars */
|
||||
}
|
||||
|
||||
/* GUTTER */
|
||||
|
||||
.CodeMirror-gutters {
|
||||
border-right: 1px solid #ddd;
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
.CodeMirror-linenumbers {}
|
||||
.CodeMirror-linenumber {
|
||||
padding: 0 3px 0 5px;
|
||||
min-width: 20px;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* CURSOR */
|
||||
|
||||
.CodeMirror div.CodeMirror-cursor {
|
||||
border-left: 1px solid black;
|
||||
z-index: 3;
|
||||
}
|
||||
/* Shown when moving in bi-directional text */
|
||||
.CodeMirror div.CodeMirror-secondarycursor {
|
||||
border-left: 1px solid silver;
|
||||
}
|
||||
.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor {
|
||||
width: auto;
|
||||
border: 0;
|
||||
background: #7e7;
|
||||
z-index: 1;
|
||||
}
|
||||
/* Can style cursor different in overwrite (non-insert) mode */
|
||||
.CodeMirror div.CodeMirror-cursor.CodeMirror-overwrite {}
|
||||
|
||||
.cm-tab { display: inline-block; }
|
||||
|
||||
/* DEFAULT THEME */
|
||||
|
||||
.cm-s-default .cm-keyword {color: #708;}
|
||||
.cm-s-default .cm-atom {color: #219;}
|
||||
.cm-s-default .cm-number {color: #164;}
|
||||
.cm-s-default .cm-def {color: #00f;}
|
||||
.cm-s-default .cm-variable {color: black;}
|
||||
.cm-s-default .cm-variable-2 {color: #05a;}
|
||||
.cm-s-default .cm-variable-3 {color: #085;}
|
||||
.cm-s-default .cm-property {color: black;}
|
||||
.cm-s-default .cm-operator {color: black;}
|
||||
.cm-s-default .cm-comment {color: #a50;}
|
||||
.cm-s-default .cm-string {color: #a11;}
|
||||
.cm-s-default .cm-string-2 {color: #f50;}
|
||||
.cm-s-default .cm-meta {color: #555;}
|
||||
.cm-s-default .cm-error {color: #f00;}
|
||||
.cm-s-default .cm-qualifier {color: #555;}
|
||||
.cm-s-default .cm-builtin {color: #30a;}
|
||||
.cm-s-default .cm-bracket {color: #997;}
|
||||
.cm-s-default .cm-tag {color: #170;}
|
||||
.cm-s-default .cm-attribute {color: #00c;}
|
||||
.cm-s-default .cm-header {color: blue;}
|
||||
.cm-s-default .cm-quote {color: #090;}
|
||||
.cm-s-default .cm-hr {color: #999;}
|
||||
.cm-s-default .cm-link {color: #00c;}
|
||||
|
||||
.cm-negative {color: #d44;}
|
||||
.cm-positive {color: #292;}
|
||||
.cm-header, .cm-strong {font-weight: bold;}
|
||||
.cm-em {font-style: italic;}
|
||||
.cm-link {text-decoration: underline;}
|
||||
|
||||
.cm-invalidchar {color: #f00;}
|
||||
|
||||
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
|
||||
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
|
||||
|
||||
/* STOP */
|
||||
|
||||
/* The rest of this file contains styles related to the mechanics of
|
||||
the editor. You probably shouldn't touch them. */
|
||||
|
||||
.CodeMirror {
|
||||
line-height: 1;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.CodeMirror-scroll {
|
||||
/* 30px is the magic margin used to hide the element's real scrollbars */
|
||||
/* See overflow: hidden in .CodeMirror */
|
||||
margin-bottom: -30px; margin-right: -30px;
|
||||
padding-bottom: 30px; padding-right: 30px;
|
||||
height: 100%;
|
||||
outline: none; /* Prevent dragging from highlighting the element */
|
||||
position: relative;
|
||||
}
|
||||
.CodeMirror-sizer {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* The fake, visible scrollbars. Used to force redraw during scrolling
|
||||
before actuall scrolling happens, thus preventing shaking and
|
||||
flickering artifacts. */
|
||||
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler {
|
||||
position: absolute;
|
||||
z-index: 6;
|
||||
display: none;
|
||||
}
|
||||
.CodeMirror-vscrollbar {
|
||||
right: 0; top: 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
.CodeMirror-hscrollbar {
|
||||
bottom: 0; left: 0;
|
||||
overflow-y: hidden;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
.CodeMirror-scrollbar-filler {
|
||||
right: 0; bottom: 0;
|
||||
z-index: 6;
|
||||
}
|
||||
|
||||
.CodeMirror-gutters {
|
||||
position: absolute; left: 0; top: 0;
|
||||
height: 100%;
|
||||
padding-bottom: 30px;
|
||||
z-index: 3;
|
||||
}
|
||||
.CodeMirror-gutter {
|
||||
height: 100%;
|
||||
padding-bottom: 30px;
|
||||
margin-bottom: -32px;
|
||||
display: inline-block;
|
||||
/* Hack to make IE7 behave */
|
||||
*zoom:1;
|
||||
*display:inline;
|
||||
}
|
||||
.CodeMirror-gutter-elt {
|
||||
position: absolute;
|
||||
cursor: default;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.CodeMirror-lines {
|
||||
cursor: text;
|
||||
}
|
||||
.CodeMirror pre {
|
||||
/* Reset some styles that the rest of the page might have set */
|
||||
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
|
||||
border-width: 0;
|
||||
background: transparent;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
margin: 0;
|
||||
white-space: pre;
|
||||
word-wrap: normal;
|
||||
line-height: inherit;
|
||||
color: inherit;
|
||||
z-index: 2;
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
}
|
||||
.CodeMirror-wrap pre {
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
word-break: normal;
|
||||
}
|
||||
.CodeMirror-linebackground {
|
||||
position: absolute;
|
||||
left: 0; right: 0; top: 0; bottom: 0;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.CodeMirror-linewidget {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.CodeMirror-widget {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.CodeMirror-wrap .CodeMirror-scroll {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.CodeMirror-measure {
|
||||
position: absolute;
|
||||
width: 100%; height: 0px;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
}
|
||||
.CodeMirror-measure pre { position: static; }
|
||||
|
||||
.CodeMirror div.CodeMirror-cursor {
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
border-right: none;
|
||||
width: 0;
|
||||
}
|
||||
.CodeMirror-focused div.CodeMirror-cursor {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.CodeMirror-selected { background: #d9d9d9; }
|
||||
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
|
||||
|
||||
.cm-searching {
|
||||
background: #ffa;
|
||||
background: rgba(255, 255, 0, .4);
|
||||
}
|
||||
|
||||
/* IE7 hack to prevent it from returning funny offsetTops on the spans */
|
||||
.CodeMirror span { *vertical-align: text-bottom; }
|
||||
|
||||
@media print {
|
||||
/* Hide the cursor when printing */
|
||||
.CodeMirror div.CodeMirror-cursor {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
5585
core/admin/assets/lib/codemirror/codemirror.js
Normal file
344
core/admin/assets/lib/codemirror/mode/markdown/index.html
vendored
Normal file
@ -0,0 +1,344 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CodeMirror: Markdown mode</title>
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="../../addon/edit/continuelist.js"></script>
|
||||
<script src="../xml/xml.js"></script>
|
||||
<script src="markdown.js"></script>
|
||||
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
||||
<link rel="stylesheet" href="../../doc/docs.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>CodeMirror: Markdown mode</h1>
|
||||
|
||||
<!-- source: http://daringfireball.net/projects/markdown/basics.text -->
|
||||
<form><textarea id="code" name="code">
|
||||
Markdown: Basics
|
||||
================
|
||||
|
||||
<ul id="ProjectSubmenu">
|
||||
<li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
|
||||
<li><a class="selected" title="Markdown Basics">Basics</a></li>
|
||||
<li><a href="/projects/markdown/syntax" title="Markdown Syntax Documentation">Syntax</a></li>
|
||||
<li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
|
||||
<li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
Getting the Gist of Markdown's Formatting Syntax
|
||||
------------------------------------------------
|
||||
|
||||
This page offers a brief overview of what it's like to use Markdown.
|
||||
The [syntax page] [s] provides complete, detailed documentation for
|
||||
every feature, but Markdown should be very easy to pick up simply by
|
||||
looking at a few examples of it in action. The examples on this page
|
||||
are written in a before/after style, showing example syntax and the
|
||||
HTML output produced by Markdown.
|
||||
|
||||
It's also helpful to simply try Markdown out; the [Dingus] [d] is a
|
||||
web application that allows you type your own Markdown-formatted text
|
||||
and translate it to XHTML.
|
||||
|
||||
**Note:** This document is itself written using Markdown; you
|
||||
can [see the source for it by adding '.text' to the URL] [src].
|
||||
|
||||
[s]: /projects/markdown/syntax "Markdown Syntax"
|
||||
[d]: /projects/markdown/dingus "Markdown Dingus"
|
||||
[src]: /projects/markdown/basics.text
|
||||
|
||||
|
||||
## Paragraphs, Headers, Blockquotes ##
|
||||
|
||||
A paragraph is simply one or more consecutive lines of text, separated
|
||||
by one or more blank lines. (A blank line is any line that looks like
|
||||
a blank line -- a line containing nothing but spaces or tabs is
|
||||
considered blank.) Normal paragraphs should not be indented with
|
||||
spaces or tabs.
|
||||
|
||||
Markdown offers two styles of headers: *Setext* and *atx*.
|
||||
Setext-style headers for `<h1>` and `<h2>` are created by
|
||||
"underlining" with equal signs (`=`) and hyphens (`-`), respectively.
|
||||
To create an atx-style header, you put 1-6 hash marks (`#`) at the
|
||||
beginning of the line -- the number of hashes equals the resulting
|
||||
HTML header level.
|
||||
|
||||
Blockquotes are indicated using email-style '`>`' angle brackets.
|
||||
|
||||
Markdown:
|
||||
|
||||
A First Level Header
|
||||
====================
|
||||
|
||||
A Second Level Header
|
||||
---------------------
|
||||
|
||||
Now is the time for all good men to come to
|
||||
the aid of their country. This is just a
|
||||
regular paragraph.
|
||||
|
||||
The quick brown fox jumped over the lazy
|
||||
dog's back.
|
||||
|
||||
### Header 3
|
||||
|
||||
> This is a blockquote.
|
||||
>
|
||||
> This is the second paragraph in the blockquote.
|
||||
>
|
||||
> ## This is an H2 in a blockquote
|
||||
|
||||
|
||||
Output:
|
||||
|
||||
<h1>A First Level Header</h1>
|
||||
|
||||
<h2>A Second Level Header</h2>
|
||||
|
||||
<p>Now is the time for all good men to come to
|
||||
the aid of their country. This is just a
|
||||
regular paragraph.</p>
|
||||
|
||||
<p>The quick brown fox jumped over the lazy
|
||||
dog's back.</p>
|
||||
|
||||
<h3>Header 3</h3>
|
||||
|
||||
<blockquote>
|
||||
<p>This is a blockquote.</p>
|
||||
|
||||
<p>This is the second paragraph in the blockquote.</p>
|
||||
|
||||
<h2>This is an H2 in a blockquote</h2>
|
||||
</blockquote>
|
||||
|
||||
|
||||
|
||||
### Phrase Emphasis ###
|
||||
|
||||
Markdown uses asterisks and underscores to indicate spans of emphasis.
|
||||
|
||||
Markdown:
|
||||
|
||||
Some of these words *are emphasized*.
|
||||
Some of these words _are emphasized also_.
|
||||
|
||||
Use two asterisks for **strong emphasis**.
|
||||
Or, if you prefer, __use two underscores instead__.
|
||||
|
||||
Output:
|
||||
|
||||
<p>Some of these words <em>are emphasized</em>.
|
||||
Some of these words <em>are emphasized also</em>.</p>
|
||||
|
||||
<p>Use two asterisks for <strong>strong emphasis</strong>.
|
||||
Or, if you prefer, <strong>use two underscores instead</strong>.</p>
|
||||
|
||||
|
||||
|
||||
## Lists ##
|
||||
|
||||
Unordered (bulleted) lists use asterisks, pluses, and hyphens (`*`,
|
||||
`+`, and `-`) as list markers. These three markers are
|
||||
interchangable; this:
|
||||
|
||||
* Candy.
|
||||
* Gum.
|
||||
* Booze.
|
||||
|
||||
this:
|
||||
|
||||
+ Candy.
|
||||
+ Gum.
|
||||
+ Booze.
|
||||
|
||||
and this:
|
||||
|
||||
- Candy.
|
||||
- Gum.
|
||||
- Booze.
|
||||
|
||||
all produce the same output:
|
||||
|
||||
<ul>
|
||||
<li>Candy.</li>
|
||||
<li>Gum.</li>
|
||||
<li>Booze.</li>
|
||||
</ul>
|
||||
|
||||
Ordered (numbered) lists use regular numbers, followed by periods, as
|
||||
list markers:
|
||||
|
||||
1. Red
|
||||
2. Green
|
||||
3. Blue
|
||||
|
||||
Output:
|
||||
|
||||
<ol>
|
||||
<li>Red</li>
|
||||
<li>Green</li>
|
||||
<li>Blue</li>
|
||||
</ol>
|
||||
|
||||
If you put blank lines between items, you'll get `<p>` tags for the
|
||||
list item text. You can create multi-paragraph list items by indenting
|
||||
the paragraphs by 4 spaces or 1 tab:
|
||||
|
||||
* A list item.
|
||||
|
||||
With multiple paragraphs.
|
||||
|
||||
* Another item in the list.
|
||||
|
||||
Output:
|
||||
|
||||
<ul>
|
||||
<li><p>A list item.</p>
|
||||
<p>With multiple paragraphs.</p></li>
|
||||
<li><p>Another item in the list.</p></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
### Links ###
|
||||
|
||||
Markdown supports two styles for creating links: *inline* and
|
||||
*reference*. With both styles, you use square brackets to delimit the
|
||||
text you want to turn into a link.
|
||||
|
||||
Inline-style links use parentheses immediately after the link text.
|
||||
For example:
|
||||
|
||||
This is an [example link](http://example.com/).
|
||||
|
||||
Output:
|
||||
|
||||
<p>This is an <a href="http://example.com/">
|
||||
example link</a>.</p>
|
||||
|
||||
Optionally, you may include a title attribute in the parentheses:
|
||||
|
||||
This is an [example link](http://example.com/ "With a Title").
|
||||
|
||||
Output:
|
||||
|
||||
<p>This is an <a href="http://example.com/" title="With a Title">
|
||||
example link</a>.</p>
|
||||
|
||||
Reference-style links allow you to refer to your links by names, which
|
||||
you define elsewhere in your document:
|
||||
|
||||
I get 10 times more traffic from [Google][1] than from
|
||||
[Yahoo][2] or [MSN][3].
|
||||
|
||||
[1]: http://google.com/ "Google"
|
||||
[2]: http://search.yahoo.com/ "Yahoo Search"
|
||||
[3]: http://search.msn.com/ "MSN Search"
|
||||
|
||||
Output:
|
||||
|
||||
<p>I get 10 times more traffic from <a href="http://google.com/"
|
||||
title="Google">Google</a> than from <a href="http://search.yahoo.com/"
|
||||
title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/"
|
||||
title="MSN Search">MSN</a>.</p>
|
||||
|
||||
The title attribute is optional. Link names may contain letters,
|
||||
numbers and spaces, but are *not* case sensitive:
|
||||
|
||||
I start my morning with a cup of coffee and
|
||||
[The New York Times][NY Times].
|
||||
|
||||
[ny times]: http://www.nytimes.com/
|
||||
|
||||
Output:
|
||||
|
||||
<p>I start my morning with a cup of coffee and
|
||||
<a href="http://www.nytimes.com/">The New York Times</a>.</p>
|
||||
|
||||
|
||||
### Images ###
|
||||
|
||||
Image syntax is very much like link syntax.
|
||||
|
||||
Inline (titles are optional):
|
||||
|
||||
![alt text](/path/to/img.jpg "Title")
|
||||
|
||||
Reference-style:
|
||||
|
||||
![alt text][id]
|
||||
|
||||
[id]: /path/to/img.jpg "Title"
|
||||
|
||||
Both of the above examples produce the same output:
|
||||
|
||||
<img src="/path/to/img.jpg" alt="alt text" title="Title" />
|
||||
|
||||
|
||||
|
||||
### Code ###
|
||||
|
||||
In a regular paragraph, you can create code span by wrapping text in
|
||||
backtick quotes. Any ampersands (`&`) and angle brackets (`<` or
|
||||
`>`) will automatically be translated into HTML entities. This makes
|
||||
it easy to use Markdown to write about HTML example code:
|
||||
|
||||
I strongly recommend against using any `<blink>` tags.
|
||||
|
||||
I wish SmartyPants used named entities like `&mdash;`
|
||||
instead of decimal-encoded entites like `&#8212;`.
|
||||
|
||||
Output:
|
||||
|
||||
<p>I strongly recommend against using any
|
||||
<code>&lt;blink&gt;</code> tags.</p>
|
||||
|
||||
<p>I wish SmartyPants used named entities like
|
||||
<code>&amp;mdash;</code> instead of decimal-encoded
|
||||
entites like <code>&amp;#8212;</code>.</p>
|
||||
|
||||
|
||||
To specify an entire block of pre-formatted code, indent every line of
|
||||
the block by 4 spaces or 1 tab. Just like with code spans, `&`, `<`,
|
||||
and `>` characters will be escaped automatically.
|
||||
|
||||
Markdown:
|
||||
|
||||
If you want your page to validate under XHTML 1.0 Strict,
|
||||
you've got to put paragraph tags in your blockquotes:
|
||||
|
||||
<blockquote>
|
||||
<p>For example.</p>
|
||||
</blockquote>
|
||||
|
||||
Output:
|
||||
|
||||
<p>If you want your page to validate under XHTML 1.0 Strict,
|
||||
you've got to put paragraph tags in your blockquotes:</p>
|
||||
|
||||
<pre><code>&lt;blockquote&gt;
|
||||
&lt;p&gt;For example.&lt;/p&gt;
|
||||
&lt;/blockquote&gt;
|
||||
</code></pre>
|
||||
</textarea></form>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
mode: 'markdown',
|
||||
lineNumbers: true,
|
||||
theme: "default",
|
||||
extraKeys: {"Enter": "newlineAndIndentContinueMarkdownList"}
|
||||
});
|
||||
</script>
|
||||
|
||||
<p>Optionally depends on the XML mode for properly highlighted inline XML blocks.</p>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-markdown</code>.</p>
|
||||
|
||||
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#markdown_*">normal</a>, <a href="../../test/index.html#verbose,markdown_*">verbose</a>.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
526
core/admin/assets/lib/codemirror/mode/markdown/markdown.js
vendored
Normal file
@ -0,0 +1,526 @@
|
||||
CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
||||
|
||||
var htmlFound = CodeMirror.mimeModes.hasOwnProperty("text/html");
|
||||
var htmlMode = CodeMirror.getMode(cmCfg, htmlFound ? "text/html" : "text/plain");
|
||||
var aliases = {
|
||||
html: "htmlmixed",
|
||||
js: "javascript",
|
||||
json: "application/json",
|
||||
c: "text/x-csrc",
|
||||
"c++": "text/x-c++src",
|
||||
java: "text/x-java",
|
||||
csharp: "text/x-csharp",
|
||||
"c#": "text/x-csharp",
|
||||
scala: "text/x-scala"
|
||||
};
|
||||
|
||||
var getMode = (function () {
|
||||
var i, modes = {}, mimes = {}, mime;
|
||||
|
||||
var list = [];
|
||||
for (var m in CodeMirror.modes)
|
||||
if (CodeMirror.modes.propertyIsEnumerable(m)) list.push(m);
|
||||
for (i = 0; i < list.length; i++) {
|
||||
modes[list[i]] = list[i];
|
||||
}
|
||||
var mimesList = [];
|
||||
for (var m in CodeMirror.mimeModes)
|
||||
if (CodeMirror.mimeModes.propertyIsEnumerable(m))
|
||||
mimesList.push({mime: m, mode: CodeMirror.mimeModes[m]});
|
||||
for (i = 0; i < mimesList.length; i++) {
|
||||
mime = mimesList[i].mime;
|
||||
mimes[mime] = mimesList[i].mime;
|
||||
}
|
||||
|
||||
for (var a in aliases) {
|
||||
if (aliases[a] in modes || aliases[a] in mimes)
|
||||
modes[a] = aliases[a];
|
||||
}
|
||||
|
||||
return function (lang) {
|
||||
return modes[lang] ? CodeMirror.getMode(cmCfg, modes[lang]) : null;
|
||||
};
|
||||
}());
|
||||
|
||||
// Should underscores in words open/close em/strong?
|
||||
if (modeCfg.underscoresBreakWords === undefined)
|
||||
modeCfg.underscoresBreakWords = true;
|
||||
|
||||
// Turn on fenced code blocks? ("```" to start/end)
|
||||
if (modeCfg.fencedCodeBlocks === undefined) modeCfg.fencedCodeBlocks = false;
|
||||
|
||||
// Turn on task lists? ("- [ ] " and "- [x] ")
|
||||
if (modeCfg.taskLists === undefined) modeCfg.taskLists = false;
|
||||
|
||||
var codeDepth = 0;
|
||||
|
||||
var header = 'header'
|
||||
, code = 'comment'
|
||||
, quote1 = 'atom'
|
||||
, quote2 = 'number'
|
||||
, list1 = 'variable-2'
|
||||
, list2 = 'variable-3'
|
||||
, list3 = 'keyword'
|
||||
, hr = 'hr'
|
||||
, image = 'tag'
|
||||
, linkinline = 'link'
|
||||
, linkemail = 'link'
|
||||
, linktext = 'link'
|
||||
, linkhref = 'string'
|
||||
, em = 'em'
|
||||
, strong = 'strong';
|
||||
|
||||
var hrRE = /^([*\-=_])(?:\s*\1){2,}\s*$/
|
||||
, ulRE = /^[*\-+]\s+/
|
||||
, olRE = /^[0-9]+\.\s+/
|
||||
, taskListRE = /^\[(x| )\](?=\s)/ // Must follow ulRE or olRE
|
||||
, headerRE = /^(?:\={1,}|-{1,})$/
|
||||
, textRE = /^[^!\[\]*_\\<>` "'(]+/;
|
||||
|
||||
function switchInline(stream, state, f) {
|
||||
state.f = state.inline = f;
|
||||
return f(stream, state);
|
||||
}
|
||||
|
||||
function switchBlock(stream, state, f) {
|
||||
state.f = state.block = f;
|
||||
return f(stream, state);
|
||||
}
|
||||
|
||||
|
||||
// Blocks
|
||||
|
||||
function blankLine(state) {
|
||||
// Reset linkTitle state
|
||||
state.linkTitle = false;
|
||||
// Reset EM state
|
||||
state.em = false;
|
||||
// Reset STRONG state
|
||||
state.strong = false;
|
||||
// Reset state.quote
|
||||
state.quote = 0;
|
||||
if (!htmlFound && state.f == htmlBlock) {
|
||||
state.f = inlineNormal;
|
||||
state.block = blockNormal;
|
||||
}
|
||||
// Mark this line as blank
|
||||
state.thisLineHasContent = false;
|
||||
return null;
|
||||
}
|
||||
|
||||
function blockNormal(stream, state) {
|
||||
|
||||
var prevLineIsList = (state.list !== false);
|
||||
if (state.list !== false && state.indentationDiff >= 0) { // Continued list
|
||||
if (state.indentationDiff < 4) { // Only adjust indentation if *not* a code block
|
||||
state.indentation -= state.indentationDiff;
|
||||
}
|
||||
state.list = null;
|
||||
} else if (state.list !== false && state.indentation > 0) {
|
||||
state.list = null;
|
||||
state.listDepth = Math.floor(state.indentation / 4);
|
||||
} else if (state.list !== false) { // No longer a list
|
||||
state.list = false;
|
||||
state.listDepth = 0;
|
||||
}
|
||||
|
||||
if (state.indentationDiff >= 4) {
|
||||
state.indentation -= 4;
|
||||
stream.skipToEnd();
|
||||
return code;
|
||||
} else if (stream.eatSpace()) {
|
||||
return null;
|
||||
} else if (stream.peek() === '#' || (state.prevLineHasContent && stream.match(headerRE)) ) {
|
||||
state.header = true;
|
||||
} else if (stream.eat('>')) {
|
||||
state.indentation++;
|
||||
state.quote = 1;
|
||||
stream.eatSpace();
|
||||
while (stream.eat('>')) {
|
||||
stream.eatSpace();
|
||||
state.quote++;
|
||||
}
|
||||
} else if (stream.peek() === '[') {
|
||||
return switchInline(stream, state, footnoteLink);
|
||||
} else if (stream.match(hrRE, true)) {
|
||||
return hr;
|
||||
} else if ((!state.prevLineHasContent || prevLineIsList) && (stream.match(ulRE, true) || stream.match(olRE, true))) {
|
||||
state.indentation += 4;
|
||||
state.list = true;
|
||||
state.listDepth++;
|
||||
if (modeCfg.taskLists && stream.match(taskListRE, false)) {
|
||||
state.taskList = true;
|
||||
}
|
||||
} else if (modeCfg.fencedCodeBlocks && stream.match(/^```([\w+#]*)/, true)) {
|
||||
// try switching mode
|
||||
state.localMode = getMode(RegExp.$1);
|
||||
if (state.localMode) state.localState = state.localMode.startState();
|
||||
switchBlock(stream, state, local);
|
||||
return code;
|
||||
}
|
||||
|
||||
return switchInline(stream, state, state.inline);
|
||||
}
|
||||
|
||||
function htmlBlock(stream, state) {
|
||||
var style = htmlMode.token(stream, state.htmlState);
|
||||
if (htmlFound && style === 'tag' && state.htmlState.type !== 'openTag' && !state.htmlState.context) {
|
||||
state.f = inlineNormal;
|
||||
state.block = blockNormal;
|
||||
}
|
||||
if (state.md_inside && stream.current().indexOf(">")!=-1) {
|
||||
state.f = inlineNormal;
|
||||
state.block = blockNormal;
|
||||
state.htmlState.context = undefined;
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
function local(stream, state) {
|
||||
if (stream.sol() && stream.match(/^```/, true)) {
|
||||
state.localMode = state.localState = null;
|
||||
state.f = inlineNormal;
|
||||
state.block = blockNormal;
|
||||
return code;
|
||||
} else if (state.localMode) {
|
||||
return state.localMode.token(stream, state.localState);
|
||||
} else {
|
||||
stream.skipToEnd();
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
// Inline
|
||||
function getType(state) {
|
||||
var styles = [];
|
||||
|
||||
if (state.taskOpen) { return "meta"; }
|
||||
if (state.taskClosed) { return "property"; }
|
||||
|
||||
if (state.strong) { styles.push(strong); }
|
||||
if (state.em) { styles.push(em); }
|
||||
|
||||
if (state.linkText) { styles.push(linktext); }
|
||||
|
||||
if (state.code) { styles.push(code); }
|
||||
|
||||
if (state.header) { styles.push(header); }
|
||||
if (state.quote) { styles.push(state.quote % 2 ? quote1 : quote2); }
|
||||
if (state.list !== false) {
|
||||
var listMod = (state.listDepth - 1) % 3;
|
||||
if (!listMod) {
|
||||
styles.push(list1);
|
||||
} else if (listMod === 1) {
|
||||
styles.push(list2);
|
||||
} else {
|
||||
styles.push(list3);
|
||||
}
|
||||
}
|
||||
|
||||
return styles.length ? styles.join(' ') : null;
|
||||
}
|
||||
|
||||
function handleText(stream, state) {
|
||||
if (stream.match(textRE, true)) {
|
||||
return getType(state);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function inlineNormal(stream, state) {
|
||||
var style = state.text(stream, state);
|
||||
if (typeof style !== 'undefined')
|
||||
return style;
|
||||
|
||||
if (state.list) { // List marker (*, +, -, 1., etc)
|
||||
state.list = null;
|
||||
return getType(state);
|
||||
}
|
||||
|
||||
if (state.taskList) {
|
||||
var taskOpen = stream.match(taskListRE, true)[1] !== "x";
|
||||
if (taskOpen) state.taskOpen = true;
|
||||
else state.taskClosed = true;
|
||||
state.taskList = false;
|
||||
return getType(state);
|
||||
}
|
||||
|
||||
state.taskOpen = false;
|
||||
state.taskClosed = false;
|
||||
|
||||
var ch = stream.next();
|
||||
|
||||
if (ch === '\\') {
|
||||
stream.next();
|
||||
return getType(state);
|
||||
}
|
||||
|
||||
// Matches link titles present on next line
|
||||
if (state.linkTitle) {
|
||||
state.linkTitle = false;
|
||||
var matchCh = ch;
|
||||
if (ch === '(') {
|
||||
matchCh = ')';
|
||||
}
|
||||
matchCh = (matchCh+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
|
||||
var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh;
|
||||
if (stream.match(new RegExp(regex), true)) {
|
||||
return linkhref;
|
||||
}
|
||||
}
|
||||
|
||||
// If this block is changed, it may need to be updated in GFM mode
|
||||
if (ch === '`') {
|
||||
var t = getType(state);
|
||||
var before = stream.pos;
|
||||
stream.eatWhile('`');
|
||||
var difference = 1 + stream.pos - before;
|
||||
if (!state.code) {
|
||||
codeDepth = difference;
|
||||
state.code = true;
|
||||
return getType(state);
|
||||
} else {
|
||||
if (difference === codeDepth) { // Must be exact
|
||||
state.code = false;
|
||||
return t;
|
||||
}
|
||||
return getType(state);
|
||||
}
|
||||
} else if (state.code) {
|
||||
return getType(state);
|
||||
}
|
||||
|
||||
if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {
|
||||
stream.match(/\[[^\]]*\]/);
|
||||
state.inline = state.f = linkHref;
|
||||
return image;
|
||||
}
|
||||
|
||||
if (ch === '[' && stream.match(/.*\](\(| ?\[)/, false)) {
|
||||
state.linkText = true;
|
||||
return getType(state);
|
||||
}
|
||||
|
||||
if (ch === ']' && state.linkText) {
|
||||
var type = getType(state);
|
||||
state.linkText = false;
|
||||
state.inline = state.f = linkHref;
|
||||
return type;
|
||||
}
|
||||
|
||||
if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, true)) {
|
||||
return switchInline(stream, state, inlineElement(linkinline, '>'));
|
||||
}
|
||||
|
||||
if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, true)) {
|
||||
return switchInline(stream, state, inlineElement(linkemail, '>'));
|
||||
}
|
||||
|
||||
if (ch === '<' && stream.match(/^\w/, false)) {
|
||||
if (stream.string.indexOf(">")!=-1) {
|
||||
var atts = stream.string.substring(1,stream.string.indexOf(">"));
|
||||
if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) {
|
||||
state.md_inside = true;
|
||||
}
|
||||
}
|
||||
stream.backUp(1);
|
||||
return switchBlock(stream, state, htmlBlock);
|
||||
}
|
||||
|
||||
if (ch === '<' && stream.match(/^\/\w*?>/)) {
|
||||
state.md_inside = false;
|
||||
return "tag";
|
||||
}
|
||||
|
||||
var ignoreUnderscore = false;
|
||||
if (!modeCfg.underscoresBreakWords) {
|
||||
if (ch === '_' && stream.peek() !== '_' && stream.match(/(\w)/, false)) {
|
||||
var prevPos = stream.pos - 2;
|
||||
if (prevPos >= 0) {
|
||||
var prevCh = stream.string.charAt(prevPos);
|
||||
if (prevCh !== '_' && prevCh.match(/(\w)/, false)) {
|
||||
ignoreUnderscore = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var t = getType(state);
|
||||
if (ch === '*' || (ch === '_' && !ignoreUnderscore)) {
|
||||
if (state.strong === ch && stream.eat(ch)) { // Remove STRONG
|
||||
state.strong = false;
|
||||
return t;
|
||||
} else if (!state.strong && stream.eat(ch)) { // Add STRONG
|
||||
state.strong = ch;
|
||||
return getType(state);
|
||||
} else if (state.em === ch) { // Remove EM
|
||||
state.em = false;
|
||||
return t;
|
||||
} else if (!state.em) { // Add EM
|
||||
state.em = ch;
|
||||
return getType(state);
|
||||
}
|
||||
} else if (ch === ' ') {
|
||||
if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces
|
||||
if (stream.peek() === ' ') { // Surrounded by spaces, ignore
|
||||
return getType(state);
|
||||
} else { // Not surrounded by spaces, back up pointer
|
||||
stream.backUp(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return getType(state);
|
||||
}
|
||||
|
||||
function linkHref(stream, state) {
|
||||
// Check if space, and return NULL if so (to avoid marking the space)
|
||||
if(stream.eatSpace()){
|
||||
return null;
|
||||
}
|
||||
var ch = stream.next();
|
||||
if (ch === '(' || ch === '[') {
|
||||
return switchInline(stream, state, inlineElement(linkhref, ch === '(' ? ')' : ']'));
|
||||
}
|
||||
return 'error';
|
||||
}
|
||||
|
||||
function footnoteLink(stream, state) {
|
||||
if (stream.match(/^[^\]]*\]:/, true)) {
|
||||
state.f = footnoteUrl;
|
||||
return linktext;
|
||||
}
|
||||
return switchInline(stream, state, inlineNormal);
|
||||
}
|
||||
|
||||
function footnoteUrl(stream, state) {
|
||||
// Check if space, and return NULL if so (to avoid marking the space)
|
||||
if(stream.eatSpace()){
|
||||
return null;
|
||||
}
|
||||
// Match URL
|
||||
stream.match(/^[^\s]+/, true);
|
||||
// Check for link title
|
||||
if (stream.peek() === undefined) { // End of line, set flag to check next line
|
||||
state.linkTitle = true;
|
||||
} else { // More content on line, check if link title
|
||||
stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true);
|
||||
}
|
||||
state.f = state.inline = inlineNormal;
|
||||
return linkhref;
|
||||
}
|
||||
|
||||
var savedInlineRE = [];
|
||||
function inlineRE(endChar) {
|
||||
if (!savedInlineRE[endChar]) {
|
||||
// Escape endChar for RegExp (taken from http://stackoverflow.com/a/494122/526741)
|
||||
endChar = (endChar+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
|
||||
// Match any non-endChar, escaped character, as well as the closing
|
||||
// endChar.
|
||||
savedInlineRE[endChar] = new RegExp('^(?:[^\\\\]|\\\\.)*?(' + endChar + ')');
|
||||
}
|
||||
return savedInlineRE[endChar];
|
||||
}
|
||||
|
||||
function inlineElement(type, endChar, next) {
|
||||
next = next || inlineNormal;
|
||||
return function(stream, state) {
|
||||
stream.match(inlineRE(endChar));
|
||||
state.inline = state.f = next;
|
||||
return type;
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
startState: function() {
|
||||
return {
|
||||
f: blockNormal,
|
||||
|
||||
prevLineHasContent: false,
|
||||
thisLineHasContent: false,
|
||||
|
||||
block: blockNormal,
|
||||
htmlState: CodeMirror.startState(htmlMode),
|
||||
indentation: 0,
|
||||
|
||||
inline: inlineNormal,
|
||||
text: handleText,
|
||||
|
||||
linkText: false,
|
||||
linkTitle: false,
|
||||
em: false,
|
||||
strong: false,
|
||||
header: false,
|
||||
taskList: false,
|
||||
list: false,
|
||||
listDepth: 0,
|
||||
quote: 0
|
||||
};
|
||||
},
|
||||
|
||||
copyState: function(s) {
|
||||
return {
|
||||
f: s.f,
|
||||
|
||||
prevLineHasContent: s.prevLineHasContent,
|
||||
thisLineHasContent: s.thisLineHasContent,
|
||||
|
||||
block: s.block,
|
||||
htmlState: CodeMirror.copyState(htmlMode, s.htmlState),
|
||||
indentation: s.indentation,
|
||||
|
||||
localMode: s.localMode,
|
||||
localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null,
|
||||
|
||||
inline: s.inline,
|
||||
text: s.text,
|
||||
linkTitle: s.linkTitle,
|
||||
em: s.em,
|
||||
strong: s.strong,
|
||||
header: s.header,
|
||||
taskList: s.taskList,
|
||||
list: s.list,
|
||||
listDepth: s.listDepth,
|
||||
quote: s.quote,
|
||||
md_inside: s.md_inside
|
||||
};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
if (stream.sol()) {
|
||||
if (stream.match(/^\s*$/, true)) {
|
||||
state.prevLineHasContent = false;
|
||||
return blankLine(state);
|
||||
} else {
|
||||
state.prevLineHasContent = state.thisLineHasContent;
|
||||
state.thisLineHasContent = true;
|
||||
}
|
||||
|
||||
// Reset state.header
|
||||
state.header = false;
|
||||
|
||||
// Reset state.taskList
|
||||
state.taskList = false;
|
||||
|
||||
// Reset state.code
|
||||
state.code = false;
|
||||
|
||||
state.f = state.block;
|
||||
var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length;
|
||||
var difference = Math.floor((indentation - state.indentation) / 4) * 4;
|
||||
if (difference > 4) difference = 4;
|
||||
var adjustedIndentation = state.indentation + difference;
|
||||
state.indentationDiff = adjustedIndentation - state.indentation;
|
||||
state.indentation = adjustedIndentation;
|
||||
if (indentation > 0) return null;
|
||||
}
|
||||
return state.f(stream, state);
|
||||
},
|
||||
|
||||
blankLine: blankLine,
|
||||
|
||||
getType: getType
|
||||
};
|
||||
|
||||
}, "xml");
|
||||
|
||||
CodeMirror.defineMIME("text/x-markdown", "markdown");
|
636
core/admin/assets/lib/codemirror/mode/markdown/test.js
vendored
Normal file
@ -0,0 +1,636 @@
|
||||
(function() {
|
||||
var mode = CodeMirror.getMode({tabSize: 4}, "markdown");
|
||||
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
|
||||
|
||||
MT("plainText",
|
||||
"foo");
|
||||
|
||||
// Code blocks using 4 spaces (regardless of CodeMirror.tabSize value)
|
||||
MT("codeBlocksUsing4Spaces",
|
||||
" [comment foo]");
|
||||
|
||||
// Code blocks using 4 spaces with internal indentation
|
||||
MT("codeBlocksUsing4SpacesIndentation",
|
||||
" [comment bar]",
|
||||
" [comment hello]",
|
||||
" [comment world]",
|
||||
" [comment foo]",
|
||||
"bar");
|
||||
|
||||
// Code blocks using 4 spaces with internal indentation
|
||||
MT("codeBlocksUsing4SpacesIndentation",
|
||||
" foo",
|
||||
" [comment bar]",
|
||||
" [comment hello]",
|
||||
" [comment world]");
|
||||
|
||||
// Code blocks using 1 tab (regardless of CodeMirror.indentWithTabs value)
|
||||
MT("codeBlocksUsing1Tab",
|
||||
"\t[comment foo]");
|
||||
|
||||
// Inline code using backticks
|
||||
MT("inlineCodeUsingBackticks",
|
||||
"foo [comment `bar`]");
|
||||
|
||||
// Block code using single backtick (shouldn't work)
|
||||
MT("blockCodeSingleBacktick",
|
||||
"[comment `]",
|
||||
"foo",
|
||||
"[comment `]");
|
||||
|
||||
// Unclosed backticks
|
||||
// Instead of simply marking as CODE, it would be nice to have an
|
||||
// incomplete flag for CODE, that is styled slightly different.
|
||||
MT("unclosedBackticks",
|
||||
"foo [comment `bar]");
|
||||
|
||||
// Per documentation: "To include a literal backtick character within a
|
||||
// code span, you can use multiple backticks as the opening and closing
|
||||
// delimiters"
|
||||
MT("doubleBackticks",
|
||||
"[comment ``foo ` bar``]");
|
||||
|
||||
// Tests based on Dingus
|
||||
// http://daringfireball.net/projects/markdown/dingus
|
||||
//
|
||||
// Multiple backticks within an inline code block
|
||||
MT("consecutiveBackticks",
|
||||
"[comment `foo```bar`]");
|
||||
|
||||
// Multiple backticks within an inline code block with a second code block
|
||||
MT("consecutiveBackticks",
|
||||
"[comment `foo```bar`] hello [comment `world`]");
|
||||
|
||||
// Unclosed with several different groups of backticks
|
||||
MT("unclosedBackticks",
|
||||
"[comment ``foo ``` bar` hello]");
|
||||
|
||||
// Closed with several different groups of backticks
|
||||
MT("closedBackticks",
|
||||
"[comment ``foo ``` bar` hello``] world");
|
||||
|
||||
// atx headers
|
||||
// http://daringfireball.net/projects/markdown/syntax#header
|
||||
|
||||
MT("atxH1",
|
||||
"[header # foo]");
|
||||
|
||||
MT("atxH2",
|
||||
"[header ## foo]");
|
||||
|
||||
MT("atxH3",
|
||||
"[header ### foo]");
|
||||
|
||||
MT("atxH4",
|
||||
"[header #### foo]");
|
||||
|
||||
MT("atxH5",
|
||||
"[header ##### foo]");
|
||||
|
||||
MT("atxH6",
|
||||
"[header ###### foo]");
|
||||
|
||||
// H6 - 7x '#' should still be H6, per Dingus
|
||||
// http://daringfireball.net/projects/markdown/dingus
|
||||
MT("atxH6NotH7",
|
||||
"[header ####### foo]");
|
||||
|
||||
// Setext headers - H1, H2
|
||||
// Per documentation, "Any number of underlining =’s or -’s will work."
|
||||
// http://daringfireball.net/projects/markdown/syntax#header
|
||||
// Ideally, the text would be marked as `header` as well, but this is
|
||||
// not really feasible at the moment. So, instead, we're testing against
|
||||
// what works today, to avoid any regressions.
|
||||
//
|
||||
// Check if single underlining = works
|
||||
MT("setextH1",
|
||||
"foo",
|
||||
"[header =]");
|
||||
|
||||
// Check if 3+ ='s work
|
||||
MT("setextH1",
|
||||
"foo",
|
||||
"[header ===]");
|
||||
|
||||
// Check if single underlining - works
|
||||
MT("setextH2",
|
||||
"foo",
|
||||
"[header -]");
|
||||
|
||||
// Check if 3+ -'s work
|
||||
MT("setextH2",
|
||||
"foo",
|
||||
"[header ---]");
|
||||
|
||||
// Single-line blockquote with trailing space
|
||||
MT("blockquoteSpace",
|
||||
"[atom > foo]");
|
||||
|
||||
// Single-line blockquote
|
||||
MT("blockquoteNoSpace",
|
||||
"[atom >foo]");
|
||||
|
||||
// No blank line before blockquote
|
||||
MT("blockquoteNoBlankLine",
|
||||
"foo",
|
||||
"[atom > bar]");
|
||||
|
||||
// Nested blockquote
|
||||
MT("blockquoteSpace",
|
||||
"[atom > foo]",
|
||||
"[number > > foo]",
|
||||
"[atom > > > foo]");
|
||||
|
||||
// Single-line blockquote followed by normal paragraph
|
||||
MT("blockquoteThenParagraph",
|
||||
"[atom >foo]",
|
||||
"",
|
||||
"bar");
|
||||
|
||||
// Multi-line blockquote (lazy mode)
|
||||
MT("multiBlockquoteLazy",
|
||||
"[atom >foo]",
|
||||
"[atom bar]");
|
||||
|
||||
// Multi-line blockquote followed by normal paragraph (lazy mode)
|
||||
MT("multiBlockquoteLazyThenParagraph",
|
||||
"[atom >foo]",
|
||||
"[atom bar]",
|
||||
"",
|
||||
"hello");
|
||||
|
||||
// Multi-line blockquote (non-lazy mode)
|
||||
MT("multiBlockquote",
|
||||
"[atom >foo]",
|
||||
"[atom >bar]");
|
||||
|
||||
// Multi-line blockquote followed by normal paragraph (non-lazy mode)
|
||||
MT("multiBlockquoteThenParagraph",
|
||||
"[atom >foo]",
|
||||
"[atom >bar]",
|
||||
"",
|
||||
"hello");
|
||||
|
||||
// Check list types
|
||||
|
||||
MT("listAsterisk",
|
||||
"foo",
|
||||
"bar",
|
||||
"",
|
||||
"[variable-2 * foo]",
|
||||
"[variable-2 * bar]");
|
||||
|
||||
MT("listPlus",
|
||||
"foo",
|
||||
"bar",
|
||||
"",
|
||||
"[variable-2 + foo]",
|
||||
"[variable-2 + bar]");
|
||||
|
||||
MT("listDash",
|
||||
"foo",
|
||||
"bar",
|
||||
"",
|
||||
"[variable-2 - foo]",
|
||||
"[variable-2 - bar]");
|
||||
|
||||
MT("listNumber",
|
||||
"foo",
|
||||
"bar",
|
||||
"",
|
||||
"[variable-2 1. foo]",
|
||||
"[variable-2 2. bar]");
|
||||
|
||||
// Lists require a preceding blank line (per Dingus)
|
||||
MT("listBogus",
|
||||
"foo",
|
||||
"1. bar",
|
||||
"2. hello");
|
||||
|
||||
// Formatting in lists (*)
|
||||
MT("listAsteriskFormatting",
|
||||
"[variable-2 * ][variable-2&em *foo*][variable-2 bar]",
|
||||
"[variable-2 * ][variable-2&strong **foo**][variable-2 bar]",
|
||||
"[variable-2 * ][variable-2&strong **][variable-2&em&strong *foo**][variable-2&em *][variable-2 bar]",
|
||||
"[variable-2 * ][variable-2&comment `foo`][variable-2 bar]");
|
||||
|
||||
// Formatting in lists (+)
|
||||
MT("listPlusFormatting",
|
||||
"[variable-2 + ][variable-2&em *foo*][variable-2 bar]",
|
||||
"[variable-2 + ][variable-2&strong **foo**][variable-2 bar]",
|
||||
"[variable-2 + ][variable-2&strong **][variable-2&em&strong *foo**][variable-2&em *][variable-2 bar]",
|
||||
"[variable-2 + ][variable-2&comment `foo`][variable-2 bar]");
|
||||
|
||||
// Formatting in lists (-)
|
||||
MT("listDashFormatting",
|
||||
"[variable-2 - ][variable-2&em *foo*][variable-2 bar]",
|
||||
"[variable-2 - ][variable-2&strong **foo**][variable-2 bar]",
|
||||
"[variable-2 - ][variable-2&strong **][variable-2&em&strong *foo**][variable-2&em *][variable-2 bar]",
|
||||
"[variable-2 - ][variable-2&comment `foo`][variable-2 bar]");
|
||||
|
||||
// Formatting in lists (1.)
|
||||
MT("listNumberFormatting",
|
||||
"[variable-2 1. ][variable-2&em *foo*][variable-2 bar]",
|
||||
"[variable-2 2. ][variable-2&strong **foo**][variable-2 bar]",
|
||||
"[variable-2 3. ][variable-2&strong **][variable-2&em&strong *foo**][variable-2&em *][variable-2 bar]",
|
||||
"[variable-2 4. ][variable-2&comment `foo`][variable-2 bar]");
|
||||
|
||||
// Paragraph lists
|
||||
MT("listParagraph",
|
||||
"[variable-2 * foo]",
|
||||
"",
|
||||
"[variable-2 * bar]");
|
||||
|
||||
// Multi-paragraph lists
|
||||
//
|
||||
// 4 spaces
|
||||
MT("listMultiParagraph",
|
||||
"[variable-2 * foo]",
|
||||
"",
|
||||
"[variable-2 * bar]",
|
||||
"",
|
||||
" [variable-2 hello]");
|
||||
|
||||
// 4 spaces, extra blank lines (should still be list, per Dingus)
|
||||
MT("listMultiParagraphExtra",
|
||||
"[variable-2 * foo]",
|
||||
"",
|
||||
"[variable-2 * bar]",
|
||||
"",
|
||||
"",
|
||||
" [variable-2 hello]");
|
||||
|
||||
// 4 spaces, plus 1 space (should still be list, per Dingus)
|
||||
MT("listMultiParagraphExtraSpace",
|
||||
"[variable-2 * foo]",
|
||||
"",
|
||||
"[variable-2 * bar]",
|
||||
"",
|
||||
" [variable-2 hello]",
|
||||
"",
|
||||
" [variable-2 world]");
|
||||
|
||||
// 1 tab
|
||||
MT("listTab",
|
||||
"[variable-2 * foo]",
|
||||
"",
|
||||
"[variable-2 * bar]",
|
||||
"",
|
||||
"\t[variable-2 hello]");
|
||||
|
||||
// No indent
|
||||
MT("listNoIndent",
|
||||
"[variable-2 * foo]",
|
||||
"",
|
||||
"[variable-2 * bar]",
|
||||
"",
|
||||
"hello");
|
||||
|
||||
// Blockquote
|
||||
MT("blockquote",
|
||||
"[variable-2 * foo]",
|
||||
"",
|
||||
"[variable-2 * bar]",
|
||||
"",
|
||||
" [variable-2&atom > hello]");
|
||||
|
||||
// Code block
|
||||
MT("blockquoteCode",
|
||||
"[variable-2 * foo]",
|
||||
"",
|
||||
"[variable-2 * bar]",
|
||||
"",
|
||||
" [comment > hello]",
|
||||
"",
|
||||
" [variable-2 world]");
|
||||
|
||||
// Code block followed by text
|
||||
MT("blockquoteCodeText",
|
||||
"[variable-2 * foo]",
|
||||
"",
|
||||
" [variable-2 bar]",
|
||||
"",
|
||||
" [comment hello]",
|
||||
"",
|
||||
" [variable-2 world]");
|
||||
|
||||
// Nested list
|
||||
|
||||
MT("listAsteriskNested",
|
||||
"[variable-2 * foo]",
|
||||
"",
|
||||
" [variable-3 * bar]");
|
||||
|
||||
MT("listPlusNested",
|
||||
"[variable-2 + foo]",
|
||||
"",
|
||||
" [variable-3 + bar]");
|
||||
|
||||
MT("listDashNested",
|
||||
"[variable-2 - foo]",
|
||||
"",
|
||||
" [variable-3 - bar]");
|
||||
|
||||
MT("listNumberNested",
|
||||
"[variable-2 1. foo]",
|
||||
"",
|
||||
" [variable-3 2. bar]");
|
||||
|
||||
MT("listMixed",
|
||||
"[variable-2 * foo]",
|
||||
"",
|
||||
" [variable-3 + bar]",
|
||||
"",
|
||||
" [keyword - hello]",
|
||||
"",
|
||||
" [variable-2 1. world]");
|
||||
|
||||
MT("listBlockquote",
|
||||
"[variable-2 * foo]",
|
||||
"",
|
||||
" [variable-3 + bar]",
|
||||
"",
|
||||
" [atom&variable-3 > hello]");
|
||||
|
||||
MT("listCode",
|
||||
"[variable-2 * foo]",
|
||||
"",
|
||||
" [variable-3 + bar]",
|
||||
"",
|
||||
" [comment hello]");
|
||||
|
||||
// Code with internal indentation
|
||||
MT("listCodeIndentation",
|
||||
"[variable-2 * foo]",
|
||||
"",
|
||||
" [comment bar]",
|
||||
" [comment hello]",
|
||||
" [comment world]",
|
||||
" [comment foo]",
|
||||
" [variable-2 bar]");
|
||||
|
||||
// List nesting edge cases
|
||||
MT("listNested",
|
||||
"[variable-2 * foo]",
|
||||
"",
|
||||
" [variable-3 * bar]",
|
||||
"",
|
||||
" [variable-2 hello]"
|
||||
);
|
||||
MT("listNested",
|
||||
"[variable-2 * foo]",
|
||||
"",
|
||||
" [variable-3 * bar]",
|
||||
"",
|
||||
" [variable-3 * foo]"
|
||||
);
|
||||
|
||||
// Code followed by text
|
||||
MT("listCodeText",
|
||||
"[variable-2 * foo]",
|
||||
"",
|
||||
" [comment bar]",
|
||||
"",
|
||||
"hello");
|
||||
|
||||
// Following tests directly from official Markdown documentation
|
||||
// http://daringfireball.net/projects/markdown/syntax#hr
|
||||
|
||||
MT("hrSpace",
|
||||
"[hr * * *]");
|
||||
|
||||
MT("hr",
|
||||
"[hr ***]");
|
||||
|
||||
MT("hrLong",
|
||||
"[hr *****]");
|
||||
|
||||
MT("hrSpaceDash",
|
||||
"[hr - - -]");
|
||||
|
||||
MT("hrDashLong",
|
||||
"[hr ---------------------------------------]");
|
||||
|
||||
// Inline link with title
|
||||
MT("linkTitle",
|
||||
"[link [[foo]]][string (http://example.com/ \"bar\")] hello");
|
||||
|
||||
// Inline link without title
|
||||
MT("linkNoTitle",
|
||||
"[link [[foo]]][string (http://example.com/)] bar");
|
||||
|
||||
// Inline link with image
|
||||
MT("linkImage",
|
||||
"[link [[][tag ![[foo]]][string (http://example.com/)][link ]]][string (http://example.com/)] bar");
|
||||
|
||||
// Inline link with Em
|
||||
MT("linkEm",
|
||||
"[link [[][link&em *foo*][link ]]][string (http://example.com/)] bar");
|
||||
|
||||
// Inline link with Strong
|
||||
MT("linkStrong",
|
||||
"[link [[][link&strong **foo**][link ]]][string (http://example.com/)] bar");
|
||||
|
||||
// Inline link with EmStrong
|
||||
MT("linkEmStrong",
|
||||
"[link [[][link&strong **][link&em&strong *foo**][link&em *][link ]]][string (http://example.com/)] bar");
|
||||
|
||||
// Image with title
|
||||
MT("imageTitle",
|
||||
"[tag ![[foo]]][string (http://example.com/ \"bar\")] hello");
|
||||
|
||||
// Image without title
|
||||
MT("imageNoTitle",
|
||||
"[tag ![[foo]]][string (http://example.com/)] bar");
|
||||
|
||||
// Image with asterisks
|
||||
MT("imageAsterisks",
|
||||
"[tag ![[*foo*]]][string (http://example.com/)] bar");
|
||||
|
||||
// Not a link. Should be normal text due to square brackets being used
|
||||
// regularly in text, especially in quoted material, and no space is allowed
|
||||
// between square brackets and parentheses (per Dingus).
|
||||
MT("notALink",
|
||||
"[[foo]] (bar)");
|
||||
|
||||
// Reference-style links
|
||||
MT("linkReference",
|
||||
"[link [[foo]]][string [[bar]]] hello");
|
||||
|
||||
// Reference-style links with Em
|
||||
MT("linkReferenceEm",
|
||||
"[link [[][link&em *foo*][link ]]][string [[bar]]] hello");
|
||||
|
||||
// Reference-style links with Strong
|
||||
MT("linkReferenceStrong",
|
||||
"[link [[][link&strong **foo**][link ]]][string [[bar]]] hello");
|
||||
|
||||
// Reference-style links with EmStrong
|
||||
MT("linkReferenceEmStrong",
|
||||
"[link [[][link&strong **][link&em&strong *foo**][link&em *][link ]]][string [[bar]]] hello");
|
||||
|
||||
// Reference-style links with optional space separator (per docuentation)
|
||||
// "You can optionally use a space to separate the sets of brackets"
|
||||
MT("linkReferenceSpace",
|
||||
"[link [[foo]]] [string [[bar]]] hello");
|
||||
|
||||
// Should only allow a single space ("...use *a* space...")
|
||||
MT("linkReferenceDoubleSpace",
|
||||
"[[foo]] [[bar]] hello");
|
||||
|
||||
// Reference-style links with implicit link name
|
||||
MT("linkImplicit",
|
||||
"[link [[foo]]][string [[]]] hello");
|
||||
|
||||
// @todo It would be nice if, at some point, the document was actually
|
||||
// checked to see if the referenced link exists
|
||||
|
||||
// Link label, for reference-style links (taken from documentation)
|
||||
|
||||
MT("labelNoTitle",
|
||||
"[link [[foo]]:] [string http://example.com/]");
|
||||
|
||||
MT("labelIndented",
|
||||
" [link [[foo]]:] [string http://example.com/]");
|
||||
|
||||
MT("labelSpaceTitle",
|
||||
"[link [[foo bar]]:] [string http://example.com/ \"hello\"]");
|
||||
|
||||
MT("labelDoubleTitle",
|
||||
"[link [[foo bar]]:] [string http://example.com/ \"hello\"] \"world\"");
|
||||
|
||||
MT("labelTitleDoubleQuotes",
|
||||
"[link [[foo]]:] [string http://example.com/ \"bar\"]");
|
||||
|
||||
MT("labelTitleSingleQuotes",
|
||||
"[link [[foo]]:] [string http://example.com/ 'bar']");
|
||||
|
||||
MT("labelTitleParenthese",
|
||||
"[link [[foo]]:] [string http://example.com/ (bar)]");
|
||||
|
||||
MT("labelTitleInvalid",
|
||||
"[link [[foo]]:] [string http://example.com/] bar");
|
||||
|
||||
MT("labelLinkAngleBrackets",
|
||||
"[link [[foo]]:] [string <http://example.com/> \"bar\"]");
|
||||
|
||||
MT("labelTitleNextDoubleQuotes",
|
||||
"[link [[foo]]:] [string http://example.com/]",
|
||||
"[string \"bar\"] hello");
|
||||
|
||||
MT("labelTitleNextSingleQuotes",
|
||||
"[link [[foo]]:] [string http://example.com/]",
|
||||
"[string 'bar'] hello");
|
||||
|
||||
MT("labelTitleNextParenthese",
|
||||
"[link [[foo]]:] [string http://example.com/]",
|
||||
"[string (bar)] hello");
|
||||
|
||||
MT("labelTitleNextMixed",
|
||||
"[link [[foo]]:] [string http://example.com/]",
|
||||
"(bar\" hello");
|
||||
|
||||
MT("linkWeb",
|
||||
"[link <http://example.com/>] foo");
|
||||
|
||||
MT("linkEmail",
|
||||
"[link <user@example.com>] foo");
|
||||
|
||||
MT("emAsterisk",
|
||||
"[em *foo*] bar");
|
||||
|
||||
MT("emUnderscore",
|
||||
"[em _foo_] bar");
|
||||
|
||||
MT("emInWordAsterisk",
|
||||
"foo[em *bar*]hello");
|
||||
|
||||
MT("emInWordUnderscore",
|
||||
"foo[em _bar_]hello");
|
||||
|
||||
// Per documentation: "...surround an * or _ with spaces, it’ll be
|
||||
// treated as a literal asterisk or underscore."
|
||||
|
||||
MT("emEscapedBySpaceIn",
|
||||
"foo [em _bar _ hello_] world");
|
||||
|
||||
MT("emEscapedBySpaceOut",
|
||||
"foo _ bar[em _hello_]world");
|
||||
|
||||
// Unclosed emphasis characters
|
||||
// Instead of simply marking as EM / STRONG, it would be nice to have an
|
||||
// incomplete flag for EM and STRONG, that is styled slightly different.
|
||||
MT("emIncompleteAsterisk",
|
||||
"foo [em *bar]");
|
||||
|
||||
MT("emIncompleteUnderscore",
|
||||
"foo [em _bar]");
|
||||
|
||||
MT("strongAsterisk",
|
||||
"[strong **foo**] bar");
|
||||
|
||||
MT("strongUnderscore",
|
||||
"[strong __foo__] bar");
|
||||
|
||||
MT("emStrongAsterisk",
|
||||
"[em *foo][em&strong **bar*][strong hello**] world");
|
||||
|
||||
MT("emStrongUnderscore",
|
||||
"[em _foo][em&strong __bar_][strong hello__] world");
|
||||
|
||||
// "...same character must be used to open and close an emphasis span.""
|
||||
MT("emStrongMixed",
|
||||
"[em _foo][em&strong **bar*hello__ world]");
|
||||
|
||||
MT("emStrongMixed",
|
||||
"[em *foo][em&strong __bar_hello** world]");
|
||||
|
||||
// These characters should be escaped:
|
||||
// \ backslash
|
||||
// ` backtick
|
||||
// * asterisk
|
||||
// _ underscore
|
||||
// {} curly braces
|
||||
// [] square brackets
|
||||
// () parentheses
|
||||
// # hash mark
|
||||
// + plus sign
|
||||
// - minus sign (hyphen)
|
||||
// . dot
|
||||
// ! exclamation mark
|
||||
|
||||
MT("escapeBacktick",
|
||||
"foo \\`bar\\`");
|
||||
|
||||
MT("doubleEscapeBacktick",
|
||||
"foo \\\\[comment `bar\\\\`]");
|
||||
|
||||
MT("escapeAsterisk",
|
||||
"foo \\*bar\\*");
|
||||
|
||||
MT("doubleEscapeAsterisk",
|
||||
"foo \\\\[em *bar\\\\*]");
|
||||
|
||||
MT("escapeUnderscore",
|
||||
"foo \\_bar\\_");
|
||||
|
||||
MT("doubleEscapeUnderscore",
|
||||
"foo \\\\[em _bar\\\\_]");
|
||||
|
||||
MT("escapeHash",
|
||||
"\\# foo");
|
||||
|
||||
MT("doubleEscapeHash",
|
||||
"\\\\# foo");
|
||||
|
||||
|
||||
// Tests to make sure GFM-specific things aren't getting through
|
||||
|
||||
MT("taskList",
|
||||
"[variable-2 * [ ]] bar]");
|
||||
|
||||
MT("fencedCodeBlocks",
|
||||
"[comment ```]",
|
||||
"foo",
|
||||
"[comment ```]");
|
||||
})();
|
5
core/admin/assets/lib/jquery/jquery.min.js
vendored
Normal file
223
core/admin/assets/lib/shortcuts.js
Normal file
@ -0,0 +1,223 @@
|
||||
/**
|
||||
* http://www.openjs.com/scripts/events/keyboard_shortcuts/
|
||||
* Version : 2.01.B
|
||||
* By Binny V A
|
||||
* License : BSD
|
||||
*/
|
||||
shortcut = {
|
||||
'all_shortcuts':{},//All the shortcuts are stored in this array
|
||||
'add': function(shortcut_combination,callback,opt) {
|
||||
//Provide a set of default options
|
||||
var default_options = {
|
||||
'type':'keydown',
|
||||
'propagate':false,
|
||||
'disable_in_input':false,
|
||||
'target':document,
|
||||
'keycode':false
|
||||
}
|
||||
if(!opt) opt = default_options;
|
||||
else {
|
||||
for(var dfo in default_options) {
|
||||
if(typeof opt[dfo] == 'undefined') opt[dfo] = default_options[dfo];
|
||||
}
|
||||
}
|
||||
|
||||
var ele = opt.target;
|
||||
if(typeof opt.target == 'string') ele = document.getElementById(opt.target);
|
||||
var ths = this;
|
||||
shortcut_combination = shortcut_combination.toLowerCase();
|
||||
|
||||
//The function to be called at keypress
|
||||
var func = function(e) {
|
||||
e = e || window.event;
|
||||
|
||||
if(opt['disable_in_input']) { //Don't enable shortcut keys in Input, Textarea fields
|
||||
var element;
|
||||
if(e.target) element=e.target;
|
||||
else if(e.srcElement) element=e.srcElement;
|
||||
if(element.nodeType==3) element=element.parentNode;
|
||||
|
||||
if(element.tagName == 'INPUT' || element.tagName == 'TEXTAREA') return;
|
||||
}
|
||||
|
||||
//Find Which key is pressed
|
||||
if (e.keyCode) code = e.keyCode;
|
||||
else if (e.which) code = e.which;
|
||||
var character = String.fromCharCode(code).toLowerCase();
|
||||
|
||||
if(code == 188) character=","; //If the user presses , when the type is onkeydown
|
||||
if(code == 190) character="."; //If the user presses , when the type is onkeydown
|
||||
|
||||
var keys = shortcut_combination.split("+");
|
||||
//Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked
|
||||
var kp = 0;
|
||||
|
||||
//Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken
|
||||
var shift_nums = {
|
||||
"`":"~",
|
||||
"1":"!",
|
||||
"2":"@",
|
||||
"3":"#",
|
||||
"4":"$",
|
||||
"5":"%",
|
||||
"6":"^",
|
||||
"7":"&",
|
||||
"8":"*",
|
||||
"9":"(",
|
||||
"0":")",
|
||||
"-":"_",
|
||||
"=":"+",
|
||||
";":":",
|
||||
"'":"\"",
|
||||
",":"<",
|
||||
".":">",
|
||||
"/":"?",
|
||||
"\\":"|"
|
||||
}
|
||||
//Special Keys - and their codes
|
||||
var special_keys = {
|
||||
'esc':27,
|
||||
'escape':27,
|
||||
'tab':9,
|
||||
'space':32,
|
||||
'return':13,
|
||||
'enter':13,
|
||||
'backspace':8,
|
||||
|
||||
'scrolllock':145,
|
||||
'scroll_lock':145,
|
||||
'scroll':145,
|
||||
'capslock':20,
|
||||
'caps_lock':20,
|
||||
'caps':20,
|
||||
'numlock':144,
|
||||
'num_lock':144,
|
||||
'num':144,
|
||||
|
||||
'pause':19,
|
||||
'break':19,
|
||||
|
||||
'insert':45,
|
||||
'home':36,
|
||||
'delete':46,
|
||||
'end':35,
|
||||
|
||||
'pageup':33,
|
||||
'page_up':33,
|
||||
'pu':33,
|
||||
|
||||
'pagedown':34,
|
||||
'page_down':34,
|
||||
'pd':34,
|
||||
|
||||
'left':37,
|
||||
'up':38,
|
||||
'right':39,
|
||||
'down':40,
|
||||
|
||||
'f1':112,
|
||||
'f2':113,
|
||||
'f3':114,
|
||||
'f4':115,
|
||||
'f5':116,
|
||||
'f6':117,
|
||||
'f7':118,
|
||||
'f8':119,
|
||||
'f9':120,
|
||||
'f10':121,
|
||||
'f11':122,
|
||||
'f12':123
|
||||
}
|
||||
|
||||
var modifiers = {
|
||||
shift: { wanted:false, pressed:false},
|
||||
ctrl : { wanted:false, pressed:false},
|
||||
alt : { wanted:false, pressed:false},
|
||||
meta : { wanted:false, pressed:false} //Meta is Mac specific
|
||||
};
|
||||
|
||||
if(e.ctrlKey) modifiers.ctrl.pressed = true;
|
||||
if(e.shiftKey) modifiers.shift.pressed = true;
|
||||
if(e.altKey) modifiers.alt.pressed = true;
|
||||
if(e.metaKey) modifiers.meta.pressed = true;
|
||||
|
||||
for(var i=0; k=keys[i],i<keys.length; i++) {
|
||||
//Modifiers
|
||||
if(k == 'ctrl' || k == 'control') {
|
||||
kp++;
|
||||
modifiers.ctrl.wanted = true;
|
||||
|
||||
} else if(k == 'shift') {
|
||||
kp++;
|
||||
modifiers.shift.wanted = true;
|
||||
|
||||
} else if(k == 'alt') {
|
||||
kp++;
|
||||
modifiers.alt.wanted = true;
|
||||
} else if(k == 'meta') {
|
||||
kp++;
|
||||
modifiers.meta.wanted = true;
|
||||
} else if(k.length > 1) { //If it is a special key
|
||||
if(special_keys[k] == code) kp++;
|
||||
|
||||
} else if(opt['keycode']) {
|
||||
if(opt['keycode'] == code) kp++;
|
||||
|
||||
} else { //The special keys did not match
|
||||
if(character == k) kp++;
|
||||
else {
|
||||
if(shift_nums[character] && e.shiftKey) { //Stupid Shift key bug created by using lowercase
|
||||
character = shift_nums[character];
|
||||
if(character == k) kp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(kp == keys.length &&
|
||||
modifiers.ctrl.pressed == modifiers.ctrl.wanted &&
|
||||
modifiers.shift.pressed == modifiers.shift.wanted &&
|
||||
modifiers.alt.pressed == modifiers.alt.wanted &&
|
||||
modifiers.meta.pressed == modifiers.meta.wanted) {
|
||||
callback(e);
|
||||
|
||||
if(!opt['propagate']) { //Stop the event
|
||||
//e.cancelBubble is supported by IE - this will kill the bubbling process.
|
||||
e.cancelBubble = true;
|
||||
e.returnValue = false;
|
||||
|
||||
//e.stopPropagation works in Firefox.
|
||||
if (e.stopPropagation) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.all_shortcuts[shortcut_combination] = {
|
||||
'callback':func,
|
||||
'target':ele,
|
||||
'event': opt['type']
|
||||
};
|
||||
//Attach the function with the event
|
||||
if(ele.addEventListener) ele.addEventListener(opt['type'], func, false);
|
||||
else if(ele.attachEvent) ele.attachEvent('on'+opt['type'], func);
|
||||
else ele['on'+opt['type']] = func;
|
||||
},
|
||||
|
||||
//Remove the shortcut - just specify the shortcut and I will remove the binding
|
||||
'remove':function(shortcut_combination) {
|
||||
shortcut_combination = shortcut_combination.toLowerCase();
|
||||
var binding = this.all_shortcuts[shortcut_combination];
|
||||
delete(this.all_shortcuts[shortcut_combination])
|
||||
if(!binding) return;
|
||||
var type = binding['event'];
|
||||
var ele = binding['target'];
|
||||
var callback = binding['callback'];
|
||||
|
||||
if(ele.detachEvent) ele.detachEvent('on'+type, callback);
|
||||
else if(ele.removeEventListener) ele.removeEventListener(type, callback, false);
|
||||
else ele['on'+type] = false;
|
||||
}
|
||||
}
|
22
core/admin/assets/lib/showdown/extensions/ghostdown.js
Normal file
@ -0,0 +1,22 @@
|
||||
(function () {
|
||||
var ghostdown = function (converter) {
|
||||
return [
|
||||
// [image] syntax
|
||||
{
|
||||
type: 'lang',
|
||||
filter: function (source) {
|
||||
return source.replace(/\n+!image\[([\d\w\s]*)\]/gi, function (match, alt, a) {
|
||||
return '<section class="image-uploader"><span class="media"><span class="hidden">Image Upload</span></span><div class="description">Add image of <strong>' + alt + '</strong></div><a class="image-url" title="Add image from URL"><span class="hidden">URL</a><a class="image-webcam" title="Add image from webcam"><span class="hidden">Webcam</a></section>';
|
||||
});
|
||||
}
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
// Client-side export
|
||||
if (typeof window !== 'undefined' && window.Showdown && window.Showdown.extensions) {
|
||||
window.Showdown.extensions.ghostdown = ghostdown;
|
||||
}
|
||||
// Server-side export
|
||||
if (typeof module !== 'undefined') module.exports = ghostdown;
|
||||
}());
|
62
core/admin/assets/lib/showdown/showdown.js
Normal file
1
core/admin/assets/sass/ie.scss
Normal file
@ -0,0 +1 @@
|
||||
/* Welcome to Compass. Use this file to write IE specific override styles. */
|
366
core/admin/assets/sass/layouts/dashboard.scss
Normal file
@ -0,0 +1,366 @@
|
||||
/*
|
||||
* These are the styles used to control the look and feel of the widgetised
|
||||
* dashboard of the Ghost admin system. The first screen you see on login.
|
||||
*
|
||||
*/
|
||||
|
||||
.widget {
|
||||
width:341px;
|
||||
height:300px;
|
||||
background:#fff;
|
||||
@include box-shadow;
|
||||
float:left;
|
||||
margin:0 15px 15px 0;
|
||||
display:none;
|
||||
}
|
||||
|
||||
.none {
|
||||
margin-right:0;
|
||||
}
|
||||
|
||||
.time {
|
||||
background-image: url(../img/dash/Time@2x.png);
|
||||
background-size: 341px 300px;
|
||||
}
|
||||
|
||||
.image {
|
||||
max-width: 100%;
|
||||
width: 682px + 15px;
|
||||
background-image: url(../img/dash/Image@2x.png);
|
||||
background-size: 697px 300px;
|
||||
}
|
||||
|
||||
.stats {
|
||||
max-width: 100%;
|
||||
width: 682px + 15px;
|
||||
height: 615px;
|
||||
background-image: url(../img/dash/Stats@2x.png);
|
||||
background-size: 697px 615px;
|
||||
}
|
||||
|
||||
.facebook {
|
||||
background-image: url(../img/dash/Facebook@2x.png);
|
||||
background-size: 341px 300px;
|
||||
}
|
||||
|
||||
.gplus {
|
||||
background-image: url(../img/dash/GooglePlus@2x.png);
|
||||
background-size: 341px 300px;
|
||||
}
|
||||
|
||||
.twitter {
|
||||
background-image: url(../img/dash/Twitter@2x.png);
|
||||
background-size: 341px 300px;
|
||||
}
|
||||
|
||||
.campaignmonitor {
|
||||
background-image: url(../img/dash/CampaignMonitor@2x.png);
|
||||
background-size: 341px 300px;
|
||||
}
|
||||
|
||||
.posts {
|
||||
background-image: url(../img/dash/PostsStats@2x.png);
|
||||
background-size: 341px 300px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.chart {
|
||||
box-sizing: border-box;
|
||||
width: 250px;
|
||||
height: 250px;
|
||||
margin: 25px auto 0 auto;
|
||||
background: #242628;
|
||||
border: #efefef 54px solid;
|
||||
border-radius: 500px;
|
||||
}
|
||||
|
||||
#poststats {
|
||||
position: relative;
|
||||
top:-54px;
|
||||
left: -54px;
|
||||
}
|
||||
|
||||
.data {
|
||||
position: absolute;
|
||||
top: 87px;
|
||||
color: $midgrey;
|
||||
font-size: 13px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.ready {
|
||||
font-size: 18px;
|
||||
vertical-align: -5%;
|
||||
margin-right: 5px;
|
||||
color: $green;
|
||||
}
|
||||
|
||||
.pending {
|
||||
font-size: 18px;
|
||||
vertical-align: -5%;
|
||||
margin-right: 5px;
|
||||
color: #f9e15d;
|
||||
}
|
||||
|
||||
.draft {
|
||||
font-size: 18px;
|
||||
vertical-align: -5%;
|
||||
margin-right: 5px;
|
||||
color: $red;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
.dashboard-controls {
|
||||
@extend %box;
|
||||
padding:0 15px;
|
||||
|
||||
.text {
|
||||
padding:12px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.controls-nav {
|
||||
float:left;
|
||||
margin-left:20px;
|
||||
ul {
|
||||
border-left: $lightgrey 1px solid;
|
||||
|
||||
li {
|
||||
margin: 0;
|
||||
border-right: 1px solid $lightgrey;
|
||||
|
||||
a {
|
||||
padding: 12px 15px;
|
||||
color: $grey;
|
||||
|
||||
span {
|
||||
color: $darkgrey;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $darkgrey;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.widget-stats {
|
||||
span {
|
||||
display: block;
|
||||
font-size: 1.6em;
|
||||
line-height: 1.2em;
|
||||
color: $grey;
|
||||
margin-bottom: 15px;
|
||||
strong {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
}
|
||||
span:first-child {
|
||||
font-size: 5.4em;
|
||||
line-height: 1.4em;
|
||||
color: #000;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 1200px) {
|
||||
.span4 .vert2 {
|
||||
.widget-stats {
|
||||
span {
|
||||
font-size: 2.6em;
|
||||
strong {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
}
|
||||
span:first-child {
|
||||
font-size: 12.4em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Time & Date Box
|
||||
.time-date {
|
||||
.time {
|
||||
font-size: 7.4em;
|
||||
line-height: 0.7em;
|
||||
border-bottom: 1px solid $lightgrey;
|
||||
span {
|
||||
font-size: 0.2em;
|
||||
color: $grey;
|
||||
text-transform: uppercase;
|
||||
font-style: normal;
|
||||
}
|
||||
@media only screen and (min-width: 1400px) {
|
||||
span {
|
||||
font-size: 0.3em;
|
||||
}
|
||||
}
|
||||
}
|
||||
.date {
|
||||
font-size: 2.2em;
|
||||
line-height: 1em;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
padding: 15px 0;
|
||||
span {
|
||||
font-size: 0.7em;
|
||||
font-weight: normal;
|
||||
display: block;
|
||||
line-height: 1em;
|
||||
color: $grey;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Post Statuses Box
|
||||
.post-statuses {
|
||||
.status-levels {
|
||||
width: 30%;
|
||||
div {
|
||||
text-indent: -9999px;
|
||||
}
|
||||
}
|
||||
.status-text {
|
||||
width: 70%;
|
||||
text-transform: uppercase;
|
||||
font-size: 1.2em;
|
||||
color: $grey;
|
||||
div {
|
||||
background: none;
|
||||
padding: 15px 0;
|
||||
}
|
||||
strong {
|
||||
font-size: 1.6em;
|
||||
width: 60px;
|
||||
padding-right: 5px;
|
||||
text-align: right;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
.scheduled {
|
||||
background: $green;
|
||||
strong {
|
||||
color: $green;
|
||||
}
|
||||
}
|
||||
.pending {
|
||||
background: #fcd039;
|
||||
strong {
|
||||
color: #fcd039;
|
||||
}
|
||||
}
|
||||
.draft {
|
||||
background: $red;
|
||||
strong {
|
||||
color: $red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.todays-traffic {
|
||||
ul {
|
||||
li {
|
||||
position: relative;
|
||||
padding: 10px;
|
||||
margin-bottom: 1px;
|
||||
div {
|
||||
position: relative;
|
||||
z-index: 99;
|
||||
}
|
||||
}
|
||||
li:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
height: 34px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 20;
|
||||
}
|
||||
li:nth-child(1):before {
|
||||
background: $blue;
|
||||
width: 80%;
|
||||
}
|
||||
li:nth-child(2):before {
|
||||
background: lighten($blue, 3%);
|
||||
width: 60%;
|
||||
}
|
||||
li:nth-child(3):before {
|
||||
background: lighten($blue, 6%);
|
||||
width: 40%;
|
||||
}
|
||||
li:nth-child(4):before {
|
||||
background: lighten($blue, 10%);
|
||||
width: 20%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table {
|
||||
width: 100%;
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
thead, tbody, tr {
|
||||
display: block;
|
||||
}
|
||||
@media only screen and (min-width: 400px) {
|
||||
thead {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
tbody {
|
||||
tr {
|
||||
background: $lightbrown;
|
||||
margin-top: 5px;
|
||||
display: block;
|
||||
position: relative;
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: 1200px) {
|
||||
tr {
|
||||
padding: 0 10px 0 40px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
}
|
||||
td {
|
||||
padding: 10px;
|
||||
text-align: right;
|
||||
color: $grey;
|
||||
strong {
|
||||
color: #000;
|
||||
}
|
||||
span {
|
||||
display: none;
|
||||
}
|
||||
@media only screen and (min-width: 500px) {
|
||||
span {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
.callout {
|
||||
color: $green;
|
||||
}
|
||||
&:first-child {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
.user-img {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: none;
|
||||
}
|
||||
@media only screen and (min-width: 1200px) {
|
||||
.user-img {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
523
core/admin/assets/sass/layouts/editor.scss
Normal file
@ -0,0 +1,523 @@
|
||||
/*
|
||||
* These styles control elements specific to the post editor screen
|
||||
* used for publishing content with Ghost.
|
||||
*
|
||||
* Table of Contents:
|
||||
*
|
||||
* Editor / Preview
|
||||
* Post Preview Content
|
||||
* Full Screen Mode
|
||||
* Publish Bar
|
||||
*/
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Editor / Preview
|
||||
============================================================================= */
|
||||
|
||||
.editor {
|
||||
|
||||
// The main post title
|
||||
.entry-title {
|
||||
@extend %box;
|
||||
height: 35px;
|
||||
padding: 10px 15px;
|
||||
margin-bottom: 15px;
|
||||
position:relative;
|
||||
|
||||
@include breakpoint($mobile) {
|
||||
@include box-shadow(none);
|
||||
}
|
||||
|
||||
input {
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding:0;
|
||||
font-size: 2em;
|
||||
font-weight: 300;
|
||||
width: 100%;
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// The two content panel wrappers, positioned left/right
|
||||
.entry-markdown { left:0; border-right:$lightbrown 2px solid; }
|
||||
.entry-preview { right:0; border-left:$lightbrown 2px solid; }
|
||||
|
||||
// The visual styles for both panels
|
||||
.entry-markdown, .entry-preview {
|
||||
@include box-sizing(border-box);
|
||||
width: 50%;
|
||||
padding: 15px;
|
||||
position: absolute;
|
||||
bottom:40px; // height of the publish bar
|
||||
top:69px; // height of the post title + margin
|
||||
background: #fff;
|
||||
@include box-shadow;
|
||||
|
||||
@include breakpoint($mobile) {
|
||||
@include box-shadow(none);
|
||||
}
|
||||
|
||||
// Convert all content areas to small boxes
|
||||
@include breakpoint($netbook) {
|
||||
top:109px;
|
||||
left:0;
|
||||
right:0;
|
||||
width:100%;
|
||||
border:none;
|
||||
z-index:100;
|
||||
min-height:380px;
|
||||
.markdown, .entry-preview-content {
|
||||
height:50px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.floatingheader {
|
||||
|
||||
// Turn headers into tabs which act as links
|
||||
// both headers set to grey/inactive colour
|
||||
@include breakpoint($netbook) {
|
||||
cursor:pointer;
|
||||
width:50%;
|
||||
border-right:$lightbrown 2px solid;
|
||||
color:#fff;
|
||||
font-weight: normal;
|
||||
background:$brown;
|
||||
position:absolute;
|
||||
top:-40px;
|
||||
left:0;
|
||||
@include box-shadow(rgba(0,0,0,0.1) 0 -2px 3px inset);
|
||||
|
||||
a {
|
||||
color:#fff;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: $brown;
|
||||
}
|
||||
|
||||
.markdown-help {
|
||||
@include icon($i-question, '', lighten($brown, 15%));
|
||||
float:right;
|
||||
|
||||
&:hover {
|
||||
@include icon($i-question, '', $brown)
|
||||
}
|
||||
}
|
||||
|
||||
.entry-word-count {
|
||||
float:right;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Give the tab with the .active class the highest z-index
|
||||
&.active {
|
||||
z-index: 200;
|
||||
}
|
||||
|
||||
// Restore the normal height of the .active tab (inactive tab stays small, hidden behind)
|
||||
&.active .markdown,
|
||||
&.active .entry-preview-content {
|
||||
height:auto;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
// Restore the white bg of the currently .active tab, remove hand cursor from currently active tab
|
||||
&.active header {
|
||||
@include breakpoint($netbook) {
|
||||
cursor:auto;
|
||||
color: $brown;
|
||||
background:#fff;
|
||||
@include box-shadow(none);
|
||||
a {
|
||||
color: $brown;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hide markdown icon + wordcount when we hit mobile
|
||||
@include breakpoint($mobile) {
|
||||
.markdown-help,
|
||||
.entry-word-count {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.entry-markdown-content {
|
||||
|
||||
textarea {
|
||||
border: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position:absolute;
|
||||
top: 0;
|
||||
right:0;
|
||||
bottom:0;
|
||||
left:0;
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.CodeMirror {
|
||||
height: auto;
|
||||
position:absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
right:0;
|
||||
bottom:0;
|
||||
font-family: $font-family-mono;
|
||||
font-size:1.1em;
|
||||
line-height:1.2em;
|
||||
color: lighten($darkgrey, 30%);
|
||||
|
||||
.CodeMirror-focused,
|
||||
.CodeMirror-selected {
|
||||
color: $darkgrey;
|
||||
background: lighten($blue, 20%);
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
::selection {
|
||||
color: $darkgrey;
|
||||
background: lighten($blue, 20%);
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.CodeMirror-lines {
|
||||
padding: 65px 0 40px 0; /* Vertical padding around content */
|
||||
@include breakpoint($netbook) {padding-top: 25px;}
|
||||
@include breakpoint($mobile) {padding: 15px 0;}
|
||||
}
|
||||
.CodeMirror pre {
|
||||
padding: 0 40px; /* Horizontal padding of content */
|
||||
@include breakpoint($mobile) {padding: 0 15px;}
|
||||
}
|
||||
|
||||
.cm-header {
|
||||
color:#000;
|
||||
font-size: 1.4em;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
.cm-string,
|
||||
.cm-link,
|
||||
.cm-comment,
|
||||
.cm-quote {color:#000;}
|
||||
|
||||
}
|
||||
|
||||
.entry-preview {
|
||||
// Align the tab of entry-preview on the right
|
||||
.floatingheader {
|
||||
@include breakpoint($netbook) {
|
||||
right:0;
|
||||
left:auto;
|
||||
border-right:none;
|
||||
border-left:$lightbrown 2px solid;
|
||||
}
|
||||
}
|
||||
|
||||
.entry-preview-content {
|
||||
position:absolute;
|
||||
top:0;
|
||||
right:0;
|
||||
bottom:0;
|
||||
left:0;
|
||||
padding: 60px 40px 40px 40px;
|
||||
overflow: auto;
|
||||
|
||||
// Tweak padding for smaller screens
|
||||
@include breakpoint($netbook) {padding-top: 20px;}
|
||||
@include breakpoint($mobile) {padding: 15px;}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Special case, when scrolling, add shadows to content headers.
|
||||
.scrolling {
|
||||
|
||||
.floatingheader {
|
||||
@include breakpoint($netbook) {
|
||||
@include box-shadow(none);
|
||||
}
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
@include breakpoint($netbook) {display:none;}
|
||||
}
|
||||
}
|
||||
.CodeMirror-scroll,
|
||||
.entry-preview-content {
|
||||
@include breakpoint($netbook) {
|
||||
@include box-shadow(0 5px 5px rgba(0,0,0,0.05) inset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}//.editor
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Post Preview Content
|
||||
============================================================================= */
|
||||
|
||||
// The styles for the actual content inside the preview
|
||||
// TODO: These should just be defaults, overridden by editor.hbs in theme dir
|
||||
.entry-preview-content,
|
||||
.content-preview-content {
|
||||
font-size:1.15em;
|
||||
line-height: 1.5em;
|
||||
|
||||
a {
|
||||
color: $blue;
|
||||
text-decoration: underline;
|
||||
}
|
||||
p {
|
||||
text-indent: 0;
|
||||
margin: 1.2em 0 1.6em;
|
||||
&:first-child {
|
||||
margin-top:0;
|
||||
}
|
||||
}
|
||||
h1 {
|
||||
font-size: 3em;
|
||||
}
|
||||
h2 {
|
||||
font-size: 2.2em;
|
||||
}
|
||||
h3 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
.btn {
|
||||
text-decoration: none;
|
||||
color: $grey;
|
||||
}
|
||||
.img-placeholder {
|
||||
border: 5px dashed $grey;
|
||||
height: 100px;
|
||||
position: relative;
|
||||
span {
|
||||
display: block;
|
||||
height: 30px;
|
||||
position: absolute;
|
||||
margin-top: -15px;
|
||||
top: 50%;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Full Screen Mode
|
||||
============================================================================= */
|
||||
|
||||
body.zen {
|
||||
background: lighten($lightbrown, 3%);
|
||||
#usermenu {display:none;}
|
||||
#global-header, #publish-bar {
|
||||
@include opacity(0);
|
||||
height:0;
|
||||
overflow: hidden;
|
||||
@include transition(all 0.5s ease-out);
|
||||
}
|
||||
|
||||
main {top: 15px;@include transition(all 0.5s ease-out);}
|
||||
.entry-markdown, .entry-preview {bottom:0;@include transition(all 0.5s ease-out);}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Publish Bar
|
||||
============================================================================= */
|
||||
|
||||
#publish-bar {
|
||||
@include box-sizing(border-box);
|
||||
height:40px;
|
||||
padding: 0;
|
||||
color: $midgrey;
|
||||
background: darken($darkgrey, 4%);
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left:0;
|
||||
right:0;
|
||||
z-index:900;
|
||||
@include box-shadow(0 -2px 8px rgba(0,0,0,0.2));
|
||||
|
||||
@include breakpoint($netbook) {font-weight:normal;}
|
||||
|
||||
button {
|
||||
min-height: 30px;
|
||||
height: 30px;
|
||||
line-height: 12px;
|
||||
padding: 0 10px;
|
||||
margin-top: 5px;
|
||||
border-top:rgba(255,255,255,0.4) 1px solid;
|
||||
}
|
||||
|
||||
.button-link { border-top: none; }
|
||||
|
||||
.options {
|
||||
width:30px;
|
||||
min-height: 30px;
|
||||
height: 30px;
|
||||
margin-top:5px;
|
||||
@include box-shadow(rgba(255,255,255,0.4) 0 1px 0 inset);
|
||||
|
||||
&.up:hover {
|
||||
@include icon($i-chevron-down) {
|
||||
margin-top:-5px;
|
||||
@include transform(rotate(540deg));
|
||||
@include transition(transform 0.6s ease);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
.splitbutton-save{
|
||||
.button-save{
|
||||
@include transition(width 0.25s ease);
|
||||
}
|
||||
|
||||
.editor-options{
|
||||
@extend %menu;
|
||||
@extend %menu-right;
|
||||
bottom: 140%;
|
||||
right: -3%;
|
||||
|
||||
a{
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#entry-categories {
|
||||
position: absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
right: 165px;
|
||||
bottom:0;
|
||||
text-transform: none;
|
||||
padding: 10px 0 0 0;
|
||||
}
|
||||
|
||||
.category-label {
|
||||
display: block;
|
||||
float:left;
|
||||
@include icon($i-tag);
|
||||
padding:1px 8px 0 8px;
|
||||
@include transition;
|
||||
|
||||
&:hover {
|
||||
cursor:pointer;
|
||||
color: $lightgrey;
|
||||
}
|
||||
}
|
||||
|
||||
.category-input {
|
||||
display: inline-block;
|
||||
color: $lightgrey;
|
||||
font-weight: 300;
|
||||
background: transparent;
|
||||
border: none;
|
||||
|
||||
&:focus {outline:none;}
|
||||
}
|
||||
|
||||
.category {
|
||||
@include icon-after($i-x, 8px, $darkgrey) {
|
||||
margin-left:4px;
|
||||
vertical-align:5%;
|
||||
text-shadow: rgba(255,255,255,0.15) 0 1px 0;
|
||||
@include transition;
|
||||
}
|
||||
display: block;
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
padding: 0 5px;
|
||||
color: $lightgrey;
|
||||
background: lighten($grey, 15%);
|
||||
@include border-radius;
|
||||
@include box-shadow(
|
||||
rgba(255,255,255,0.2) 0 1px 0 inset,
|
||||
#000 0 1px 3px
|
||||
);
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
@include icon-after($i-x, 8px, $lightgrey) {text-shadow: none;}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.suggestions {
|
||||
@extend %menu;
|
||||
bottom: 100%;
|
||||
|
||||
li.selected{
|
||||
background: $blue;
|
||||
@include box-shadow(
|
||||
rgba(255,255,255,0.2) 0 1px 0 inset,
|
||||
rgba(0,0,0,0.5) 0 1px 5px
|
||||
);
|
||||
}
|
||||
|
||||
mark{
|
||||
background: none;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
#entry-settings {
|
||||
@include icon($i-settings, 1.1em){vertical-align:0;};
|
||||
@include box-sizing(border-box);
|
||||
display:inline-block;
|
||||
padding: 0 10px;
|
||||
line-height: 1.8em;
|
||||
color: $midgrey;
|
||||
@include transition;
|
||||
|
||||
&:hover {
|
||||
color: $lightgrey;
|
||||
}
|
||||
}
|
||||
|
||||
#entry-settings-menu {
|
||||
position: absolute;
|
||||
bottom:50px;
|
||||
right:-5px;
|
||||
}
|
||||
|
||||
#entry-actions {
|
||||
margin-right:6px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#entry-actions-menu {
|
||||
position: absolute;
|
||||
bottom:50px;
|
||||
right:-5px;
|
||||
}
|
138
core/admin/assets/sass/layouts/login.scss
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* These styles control elements specific to the Ghost admin login screen.
|
||||
*
|
||||
* Table of Contents:
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/* =============================================================================
|
||||
Login
|
||||
============================================================================= */
|
||||
|
||||
.ghost-login {
|
||||
color: $midgrey;
|
||||
|
||||
@include breakpoint($mobile) {
|
||||
background: $lightbrown;
|
||||
}
|
||||
|
||||
main {
|
||||
max-width: 530px;
|
||||
margin: 240px auto;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
background: #fff;
|
||||
@include border-radius(4px);
|
||||
border-top: $darkgrey 15px solid;
|
||||
@include box-shadow;
|
||||
|
||||
@include breakpoint(630px) {
|
||||
max-width: 264px;
|
||||
}
|
||||
}
|
||||
|
||||
.login-logo {
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
margin: 80px 0 70px 0;
|
||||
|
||||
@include breakpoint(630px) {
|
||||
max-width: 235px;
|
||||
margin: 40px 0;
|
||||
}
|
||||
}
|
||||
|
||||
#login {
|
||||
@include box-sizing(border-box);
|
||||
max-width: 530px;
|
||||
padding: 15px;
|
||||
background: $darkgrey;
|
||||
@include border-radius(0 0 4px 4px);
|
||||
|
||||
@include breakpoint(630px) {
|
||||
max-width: 264px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
div {
|
||||
position:relative;
|
||||
margin:0 0 5px 0;
|
||||
background: lighten($darkgrey, 15%);
|
||||
float: left;
|
||||
}
|
||||
|
||||
input {
|
||||
display:inline-block;
|
||||
clear:both;
|
||||
margin:0;
|
||||
padding-left: 8px;
|
||||
width: 168px;
|
||||
position: relative;
|
||||
border: none;
|
||||
color: #fff;
|
||||
font-size: 1.1em;
|
||||
background: transparent;
|
||||
@include transition(none);
|
||||
|
||||
&:focus {
|
||||
background: lighten($darkgrey, 22%);
|
||||
border-color: #000;
|
||||
}
|
||||
|
||||
@include breakpoint(630px) {
|
||||
width:201px;
|
||||
@include transition(none);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.email-wrap {
|
||||
position:relative;
|
||||
@include icon($i-mail, 12px) {position:absolute;bottom:8px;left:8px;z-index:100;};
|
||||
margin-right: 2px;
|
||||
@include border-radius(2px 0 0 2px);
|
||||
|
||||
@include breakpoint(630px) {
|
||||
margin-right:0;
|
||||
@include border-radius(2px);
|
||||
}
|
||||
|
||||
.email {
|
||||
padding-left: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.password-wrap {
|
||||
position:relative;
|
||||
@include icon($i-lock, 10px) {position:absolute;bottom:9px;left:11px;z-index:100;};
|
||||
@include border-radius(0 2px 2px 0);
|
||||
|
||||
@include breakpoint(630px) {
|
||||
@include border-radius(2px);
|
||||
}
|
||||
|
||||
.password {
|
||||
padding-left: 28px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
button {
|
||||
width: 80px;
|
||||
height: 30px;
|
||||
margin:0 0 0 15px;
|
||||
padding: 9px;
|
||||
min-height: 30px;
|
||||
min-width: 80px;
|
||||
@include box-shadow(rgba(255,255,255,0.15) 0 1px 0 inset);
|
||||
|
||||
@include breakpoint(630px) {
|
||||
margin:0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}//.ghost-login
|
||||
|
245
core/admin/assets/sass/layouts/manage.scss
Normal file
@ -0,0 +1,245 @@
|
||||
/*
|
||||
* These styles control elements specific to the mage posts screen
|
||||
* used for previewing and reading existing content in Ghost.
|
||||
*
|
||||
* Table of Contents:
|
||||
*
|
||||
* Manage
|
||||
* Preview
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Manage
|
||||
============================================================================= */
|
||||
|
||||
.manage {
|
||||
|
||||
.content-list {
|
||||
@include box-sizing(border-box);
|
||||
width: 35%;
|
||||
padding: 15px;
|
||||
position: absolute;
|
||||
bottom:0;
|
||||
top:0;
|
||||
left:0;
|
||||
border-right:$lightbrown 2px solid;
|
||||
background: #fff;
|
||||
@include box-shadow;
|
||||
|
||||
@include breakpoint(900px) {
|
||||
width:300px;
|
||||
}
|
||||
@include breakpoint($tablet) {
|
||||
width:auto;
|
||||
right:0;
|
||||
z-index: 500;
|
||||
border:none;
|
||||
}
|
||||
|
||||
|
||||
.content-filter {
|
||||
position:relative;
|
||||
z-index: 300;
|
||||
> a {
|
||||
padding: 5px;
|
||||
margin-left:-5px;
|
||||
}
|
||||
}
|
||||
|
||||
.button-add {
|
||||
@include icon($i-add);
|
||||
position:absolute;
|
||||
top:10px;
|
||||
right:15px;
|
||||
z-index: 700;
|
||||
color: #fff;
|
||||
padding-left:5px;
|
||||
}
|
||||
|
||||
|
||||
.content-list-content {
|
||||
position:absolute;
|
||||
top:0;
|
||||
right:0;
|
||||
bottom:0;
|
||||
left:0;
|
||||
overflow: auto;
|
||||
padding-top: 40px;
|
||||
}
|
||||
|
||||
.entry-title {
|
||||
font-size: 1.4em;
|
||||
line-height:1.1em;
|
||||
margin-bottom:0.5em;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.views {
|
||||
@include icon($i-stats, 10px, $brown);
|
||||
float:right;
|
||||
text-align: right;
|
||||
margin-left:15px;
|
||||
@include breakpoint($tablet) {
|
||||
float:none;
|
||||
}
|
||||
}
|
||||
|
||||
.featured .date {
|
||||
@include icon($i-featured, 11px) {
|
||||
margin-right:12px;
|
||||
vertical-align: 0;
|
||||
};
|
||||
}
|
||||
|
||||
ol {
|
||||
list-style: none;
|
||||
padding:0;
|
||||
margin:0;
|
||||
border-top: $lightbrown 1px solid;
|
||||
|
||||
li {
|
||||
margin:0;
|
||||
padding: 0;
|
||||
border-bottom: $lightbrown 1px solid;
|
||||
position:relative;
|
||||
|
||||
a {
|
||||
|
||||
display:block;
|
||||
padding:20px 15px;
|
||||
color: $brown;
|
||||
@include breakpoint($mobile) { padding:15px; }
|
||||
@include breakpoint($tablet) { padding-right: 40px; }
|
||||
|
||||
@include icon-after($i-chevron) {
|
||||
position:absolute;
|
||||
top:50%;
|
||||
margin-top:-6px;
|
||||
right:15px;
|
||||
}
|
||||
@include breakpoint($biggerthan-tablet) { &::after {display: none} }
|
||||
|
||||
&:hover { text-decoration: none; }
|
||||
|
||||
}
|
||||
|
||||
}//li
|
||||
|
||||
li.active {
|
||||
@include breakpoint($biggerthan-tablet) {
|
||||
// only apply active styles on larger devices
|
||||
|
||||
border-bottom: lighten($midgrey, 40%) 1px solid;
|
||||
background: lighten($midgrey, 45%);
|
||||
@include box-shadow(
|
||||
lighten($midgrey, 40%) 0 -1px 0, // top border
|
||||
rgba(0,0,0,0.06) 7px 0 0 inset, // big left border
|
||||
lighten($midgrey, 40%) 1px 0 0 inset // small left border
|
||||
);
|
||||
|
||||
a:hover {
|
||||
@include box-shadow(rgba(0,0,0,0.1) 7px 0 0 inset);
|
||||
@include transition(all 0.4s ease);
|
||||
}
|
||||
|
||||
.entry-title { font-weight: bold; }
|
||||
.entry-meta { color: $darkgrey; }
|
||||
|
||||
.views {
|
||||
@include icon($i-stats, 10px, $darkgrey);
|
||||
color: $darkgrey;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
}
|
||||
}//li.active
|
||||
}
|
||||
|
||||
}//.content-list
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Preview
|
||||
============================================================================= */
|
||||
|
||||
.content-preview {
|
||||
@include box-sizing(border-box);
|
||||
width: 65%;
|
||||
padding: 15px;
|
||||
position: absolute;
|
||||
bottom:0;
|
||||
top:0;
|
||||
right:0;
|
||||
border-left:$lightbrown 2px solid;
|
||||
background: #fff;
|
||||
@include box-shadow;
|
||||
@include breakpoint(900px) {
|
||||
width: auto;
|
||||
left: 300px;
|
||||
}
|
||||
|
||||
.unfeatured {
|
||||
@include icon($i-unfeatured, 14px);
|
||||
vertical-align: -6%;
|
||||
margin: 0 7px 0 -5px;
|
||||
padding: 5px;
|
||||
}
|
||||
.featured {
|
||||
@include icon($i-featured, 14px);
|
||||
vertical-align: -6%;
|
||||
margin: 0 7px 0 -5px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.normal {
|
||||
text-transform: none;
|
||||
margin:0 3px;
|
||||
}
|
||||
|
||||
.content-preview-content {
|
||||
position: absolute;
|
||||
top:0;
|
||||
right:0;
|
||||
bottom:0;
|
||||
left:0;
|
||||
overflow: auto;
|
||||
padding: 80px 40px;
|
||||
|
||||
.wrapper {
|
||||
max-width: 700px;
|
||||
margin:0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.post-controls {
|
||||
float:right;
|
||||
position: relative;
|
||||
|
||||
ul {
|
||||
position: absolute;
|
||||
top:15px;
|
||||
right:-15px;
|
||||
}
|
||||
}
|
||||
|
||||
.post-edit {
|
||||
@include icon($i-edit, 14px);
|
||||
margin-right:7px;
|
||||
padding: 5px;
|
||||
}
|
||||
.post-settings {
|
||||
@include icon($i-settings, 14px);
|
||||
padding: 5px;
|
||||
margin-right: -5px;
|
||||
}
|
||||
|
||||
img {
|
||||
width:100%;
|
||||
height:auto;
|
||||
}
|
||||
|
||||
}//.preview-post
|
||||
|
||||
}//.manage
|
226
core/admin/assets/sass/layouts/settings.scss
Normal file
@ -0,0 +1,226 @@
|
||||
/*
|
||||
* These styles control elements specific to the settings screen
|
||||
* used for configuring your Ghost install.
|
||||
*
|
||||
* Table of Contents:
|
||||
*
|
||||
* Settings
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Settings
|
||||
============================================================================= */
|
||||
|
||||
.settings {
|
||||
|
||||
// The main white bg for the page
|
||||
.wrapper {
|
||||
background: #fff;
|
||||
@include box-shadow;
|
||||
position:absolute;
|
||||
top:0;
|
||||
bottom:0;
|
||||
left:0;
|
||||
right:0;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
.title {
|
||||
text-transform: uppercase;
|
||||
font-weight: normal;
|
||||
font-size: 1.6em;
|
||||
line-height: 0.8em;
|
||||
margin:0 0 18px 0;
|
||||
padding:0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Sidebar
|
||||
============================================================================= */
|
||||
|
||||
//The whole left column sidebar, duh.
|
||||
.settings-sidebar {
|
||||
width:20%;
|
||||
position:absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
bottom:0;
|
||||
z-index: 700;
|
||||
@include box-shadow($lightbrown 1px 0 0);
|
||||
@include breakpoint($tablet) {
|
||||
width:100%;
|
||||
@include box-shadow(none);
|
||||
}
|
||||
|
||||
> header {
|
||||
height: 17px;
|
||||
padding: 30px 15px 30px 40px;
|
||||
margin-bottom: 0;
|
||||
border-bottom: none;
|
||||
@include box-shadow(#edece4 0 -1px 0 inset);
|
||||
@include breakpoint($netbook) {
|
||||
padding-left: 15px;
|
||||
};
|
||||
}
|
||||
}//.settings-sidebar
|
||||
|
||||
//Main settings-menu styles, apply to every item
|
||||
.settings-menu {
|
||||
position:absolute;
|
||||
top: 77px; //30px + 17px title + 30px
|
||||
left:0;
|
||||
bottom:0;
|
||||
right:-1px;
|
||||
overflow: auto;
|
||||
@include breakpoint($tablet) { right:0; };
|
||||
|
||||
ul {
|
||||
border-top:none;
|
||||
@include breakpoint($tablet) { border-bottom: #edece4 1px solid; }
|
||||
}
|
||||
|
||||
li {
|
||||
margin-right:1px;
|
||||
border-top: #fff 1px solid;
|
||||
@include breakpoint($tablet) {
|
||||
margin-right:0;
|
||||
border-top: #edece4 1px solid;
|
||||
}
|
||||
|
||||
a {
|
||||
padding:15px 15px 15px 40px;
|
||||
border-bottom:none;
|
||||
@include breakpoint($netbook) { padding-left: 15px; }
|
||||
@include breakpoint($tablet) {
|
||||
@include icon-after($i-chevron) {float:right;margin-top:5px;};
|
||||
}
|
||||
}
|
||||
|
||||
&:first-child { border-top: none; }
|
||||
&:first-child.active { border-top:none; }
|
||||
|
||||
&.active {
|
||||
@include breakpoint($biggerthan-tablet) {
|
||||
// only apply active styles on larger devices
|
||||
|
||||
margin-right:0;
|
||||
position:relative;
|
||||
z-index: 300;
|
||||
border-top: #edece4 1px solid;
|
||||
@include box-shadow(#fff 1px 0 0, #edece4 0 1px 0);
|
||||
@include transition;
|
||||
|
||||
a {
|
||||
color: $darkgrey;
|
||||
font-weight: bold;
|
||||
background: #fff;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}//.active
|
||||
|
||||
}//li
|
||||
|
||||
// Give all icons some space
|
||||
li a:before {
|
||||
margin-right: 20px;
|
||||
@include breakpoint($netbook) {
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the icons for specific menu items
|
||||
.general a { @include icon($i-settings) }
|
||||
.publishing a { @include icon($i-content) }
|
||||
.services a { @include icon($i-services) }
|
||||
.users a { @include icon($i-users) }
|
||||
.appearance a { @include icon($i-appearance) }
|
||||
.plugins a { @include icon($i-plugins) }
|
||||
|
||||
}//.settings-menu
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Content
|
||||
============================================================================= */
|
||||
|
||||
// The main content panel on the right
|
||||
.settings-content {
|
||||
padding:0;
|
||||
position:absolute;
|
||||
top:0;
|
||||
right:0;
|
||||
left:20%;
|
||||
bottom:0;
|
||||
@include breakpoint($tablet) { display: none; }
|
||||
|
||||
display: none;
|
||||
&.active {display:block;}
|
||||
|
||||
> header {
|
||||
height: 17px;
|
||||
padding: 30px 220px 29px 40px;
|
||||
border-bottom:$lightbrown 1px solid;
|
||||
margin-bottom:40px;
|
||||
text-transform: none;
|
||||
font-weight: normal;
|
||||
line-height: inherit;
|
||||
color: inherit;
|
||||
@include breakpoint($netbook) { padding-left:15px; }
|
||||
@include breakpoint($letterbox) {
|
||||
height: auto;
|
||||
padding: 5px;
|
||||
position: absolute;
|
||||
top:0;
|
||||
right:0;
|
||||
border:none;
|
||||
|
||||
.title { display:none; }
|
||||
}
|
||||
|
||||
}//header
|
||||
|
||||
.page-actions {
|
||||
position:absolute;
|
||||
top:20px;
|
||||
right:40px;
|
||||
z-index: 700;
|
||||
font-size: 1em;
|
||||
@include breakpoint($netbook) { right:15px; }
|
||||
|
||||
.button-add {
|
||||
position:relative;
|
||||
padding-left:50px;
|
||||
@include icon($i-add, 1.4em, rgba(255,255,255,0.6)) {
|
||||
position: absolute;
|
||||
top:0;
|
||||
padding:9px 8px 0 0;
|
||||
left:9px;
|
||||
bottom:0;
|
||||
width: 20px;
|
||||
border-right: darken($green, 8%) 1px solid;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
position: absolute;
|
||||
top:77px; //30px + 17px title + 30px
|
||||
right:0;
|
||||
left:0;
|
||||
bottom:0;
|
||||
overflow:auto;
|
||||
padding:40px;
|
||||
@include breakpoint($netbook) { padding-left:15px; }
|
||||
@include breakpoint($letterbox) { top: 0; }
|
||||
}
|
||||
|
||||
}//.settings-content
|
||||
|
||||
}//.settings
|
16
core/admin/assets/sass/modules/animations.scss
Normal file
@ -0,0 +1,16 @@
|
||||
@-webkit-keyframes off-canvas {
|
||||
0% { left:0; }
|
||||
100% { left:300px; }
|
||||
}
|
||||
@-moz-keyframes off-canvas {
|
||||
0% { opacity: 0; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
@-o-keyframes off-canvas {
|
||||
0% { opacity: 0; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
@keyframes off-canvas {
|
||||
0% { opacity: 0; }
|
||||
100% { opacity: 1; }
|
||||
}
|
546
core/admin/assets/sass/modules/breakpoint.scss
Normal file
@ -0,0 +1,546 @@
|
||||
/*
|
||||
* Breakpoint Sass 1.3.0
|
||||
* Last updated: 2012-08-28
|
||||
* Copyright: Mason Wendell 2012 - MIT Licensed
|
||||
* Source: https://github.com/canarymason/breakpoint
|
||||
*/
|
||||
|
||||
//////////////////////////////
|
||||
// Default Variables
|
||||
//////////////////////////////
|
||||
$breakpoint-default-feature: 'min-width' !default;
|
||||
$breakpoint-default-media: 'all' !default;
|
||||
$breakpoint-force-media-all: false !default;
|
||||
$breakpoint-default-pair: 'width' !default;
|
||||
$breakpoint-to-ems: false !default;
|
||||
$breakpoint-prefixes: 'webkit' 'moz' !default;
|
||||
$breakpoint-prefixed-queries: 'device-pixel-ratio' 'min-device-pixel-ratio' 'max-device-pixel-ratio' !default;
|
||||
|
||||
$breakpoint-no-queries: false !default;
|
||||
$breakpoint-no-query-wrappers: false !default;
|
||||
|
||||
$breakpoint-base-font-size: false;
|
||||
|
||||
//////////////////////////////
|
||||
// Converts the input value to Base EMs
|
||||
//////////////////////////////
|
||||
@function breakpoint-to-base-em($value, $base-font-size: false) {
|
||||
$value-unit: unit($value);
|
||||
|
||||
// Will convert relative EMs into root EMs.
|
||||
@if $base-font-size and type-of($base-font-size) == 'number' and $value-unit == 'em' {
|
||||
$base-unit: unit($base-font-size);
|
||||
|
||||
@if $base-unit == 'px' or $base-unit == '%' or $base-unit == 'em' or $base-unit == 'pt' {
|
||||
@return base-conversion($value) / base-conversion($base-font-size) * 1em;
|
||||
}
|
||||
@else {
|
||||
@warn '#{$base-font-size} is not set in valid units for font size!';
|
||||
@return false;
|
||||
}
|
||||
}
|
||||
@else {
|
||||
@return base-conversion($value);
|
||||
}
|
||||
}
|
||||
|
||||
@function base-conversion($value) {
|
||||
$unit: unit($value);
|
||||
|
||||
@if $unit == 'px' {
|
||||
@return $value / 16px * 1em;
|
||||
}
|
||||
@else if $unit == '%' {
|
||||
@return $value / 100% * 1em;
|
||||
}
|
||||
@else if $unit == 'em' {
|
||||
@return $value;
|
||||
}
|
||||
@else if $unit == 'pt' {
|
||||
@return $value / 12pt * 1em;
|
||||
}
|
||||
@else {
|
||||
@return $value;
|
||||
// @warn 'Everything is terrible! What have you done?!';
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// Returns whether the feature can have a min/max pair
|
||||
//////////////////////////////
|
||||
@function breakpoint-min-max($feature) {
|
||||
@if $feature == 'color' or $feature == 'color-index' or $feature == 'aspect-ratio' or $feature == 'device-height' or $feature == 'device-width' or $feature == 'height' or $feature == 'monochrome' or $feature == 'resolution' or $feature == 'width' or $feature == 'device-pixel-ratio' {
|
||||
@return true;
|
||||
}
|
||||
@else {
|
||||
@return false;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// Returns whether the feature can have a string value
|
||||
//////////////////////////////
|
||||
@function breakpoint-string-value($feature) {
|
||||
@if $feature == 'orientation' or $feature == 'scan' or $feature == 'color' or $feature == 'resolution' or $feature == 'min-resolution' or $feature == 'max-resolution' {
|
||||
@return true;
|
||||
}
|
||||
@else {
|
||||
@return false;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// Experimental Media Queries
|
||||
//////////////////////////////
|
||||
@function breakpoint-experimental($property, $prefix) {
|
||||
@if $property == 'min-device-pixel-ratio' {
|
||||
@if $prefix == 'webkit' {
|
||||
@return '-#{$prefix}-#{$property}';
|
||||
}
|
||||
@else if $prefix == 'moz' {
|
||||
@return 'min--#{$prefix}-device-pixel-ratio';
|
||||
}
|
||||
@else {
|
||||
@warn '#{$property} is not fully supported in -#{prefix}';
|
||||
@return 'ERROR';
|
||||
}
|
||||
}
|
||||
@else if $property == 'max-device-pixel-ratio' {
|
||||
@if $prefix == 'webkit' {
|
||||
@return '-#{$prefix}-#{$property}';
|
||||
}
|
||||
@else if $prefix == 'moz' {
|
||||
@return 'max--#{$prefix}-device-pixel-ratio';
|
||||
}
|
||||
@else {
|
||||
@warn '#{$property} is not fully supported in -#{prefix}';
|
||||
@return 'ERROR';
|
||||
}
|
||||
}
|
||||
@else {
|
||||
@return '-#{$prefix}-#{$property}';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
// Private Breakpoint Variables
|
||||
//////////////////////////////
|
||||
$TXkgdmFyaWFibGUhIEdvIGF3YXkh: () !default;
|
||||
|
||||
//////////////////////////////
|
||||
// Breakpoint Get Context
|
||||
// $feature: Input feature to get it's current MQ context. Returns false if no context
|
||||
//////////////////////////////
|
||||
@function breakpoint-get-context($feature) {
|
||||
@each $context in $TXkgdmFyaWFibGUhIEdvIGF3YXkh {
|
||||
@if $feature == nth($context, 1) {
|
||||
@return nth($context, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@return false;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// Private function to set context
|
||||
//////////////////////////////
|
||||
@function U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh($feature, $value) {
|
||||
@if $value == 'monochrome' {
|
||||
$feature: 'monochrome';
|
||||
}
|
||||
|
||||
$append: $feature;
|
||||
$append: join($append, $value, space);
|
||||
|
||||
$TXkgdmFyaWFibGUhIEdvIGF3YXkh: append($TXkgdmFyaWFibGUhIEdvIGF3YXkh, $append, comma);
|
||||
|
||||
@return true;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// Private function to reset context
|
||||
//////////////////////////////
|
||||
@mixin TXkgcmVzZXQhIEdvIGF3YXkh {
|
||||
$TXkgdmFyaWFibGUhIEdvIGF3YXkh: ();
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// Breakpoint Mixin
|
||||
//////////////////////////////
|
||||
@mixin breakpoint($breakpoint, $media: $breakpoint-default-media, $no-query: false, $base-font-size: $breakpoint-base-font-size) {
|
||||
// Query and Media String Defaults
|
||||
$query: false !default;
|
||||
$query-holder: false !default;
|
||||
$media-string: false !default;
|
||||
$do-prefix: false !default;
|
||||
|
||||
$webkit: false !default;
|
||||
$webkit-first: true !default;
|
||||
$moz: false !default;
|
||||
$moz-first: true !default;
|
||||
$o: false !default;
|
||||
$o-first: true !default;
|
||||
$ms: false !default;
|
||||
$ms-first: true !default;
|
||||
|
||||
// Holder for Count
|
||||
$first: true !default;
|
||||
|
||||
// Reset Context
|
||||
@include TXkgcmVzZXQhIEdvIGF3YXkh;
|
||||
|
||||
// Set Media Context
|
||||
$context: U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh('media', $media);
|
||||
|
||||
// Initialize Query String
|
||||
@if $media != 'all' or $breakpoint-force-media-all {
|
||||
$media-string: "#{$media} ";
|
||||
}
|
||||
@else {
|
||||
$media-string: "";
|
||||
}
|
||||
|
||||
// If we have a single query, let's just work with that.
|
||||
@if is_breakpoint_list($breakpoint) == false {
|
||||
@each $prefix-query in $breakpoint-prefixed-queries {
|
||||
@if $do-prefix == false {
|
||||
$do-prefix: featureExists($prefix-query, $breakpoint);
|
||||
}
|
||||
}
|
||||
@if $do-prefix {
|
||||
@each $prfx in $breakpoint-prefixes {
|
||||
@if $prfx == 'webkit' {
|
||||
$webkit: breakpoint-switch($breakpoint, $media-string, true, $prfx, $base-font-size: $base-font-size);
|
||||
}
|
||||
|
||||
@if $prfx == 'moz' {
|
||||
$moz: breakpoint-switch($breakpoint, $media-string, true, $prfx, $base-font-size: $base-font-size);
|
||||
}
|
||||
|
||||
@if $prfx == 'o' {
|
||||
$o: breakpoint-switch($breakpoint, $media-string, true, $prfx, $base-font-size: $base-font-size);
|
||||
}
|
||||
|
||||
@if $prfx == 'ms' {
|
||||
$ms: breakpoint-switch($breakpoint, $media-string, true, $prfx, $base-font-size: $base-font-size);
|
||||
}
|
||||
}
|
||||
}
|
||||
@else {
|
||||
$query: breakpoint-switch($breakpoint, $media-string, true, $base-font-size: $base-font-size);
|
||||
}
|
||||
}
|
||||
@else {
|
||||
// See if Prefix Query exists
|
||||
@each $prefix-query in $breakpoint-prefixed-queries {
|
||||
@if $do-prefix == false {
|
||||
$do-prefix: featureExists($prefix-query, $breakpoint);
|
||||
}
|
||||
}
|
||||
|
||||
@if $do-prefix {
|
||||
@each $prfx in $breakpoint-prefixes {
|
||||
@each $bkpt in $breakpoint {
|
||||
@if $prfx == 'webkit' {
|
||||
@if $webkit-first {
|
||||
$webkit: breakpoint-switch($bkpt, $media-string, true, $prfx, $base-font-size: $base-font-size);
|
||||
$webkit-first: false;
|
||||
}
|
||||
@else {
|
||||
$webkit: join($webkit, breakpoint-switch($bkpt, $media-string, $prefix: $prfx, $base-font-size: $base-font-size));
|
||||
}
|
||||
}
|
||||
|
||||
@if $prfx == 'moz' {
|
||||
@if $moz-first {
|
||||
$moz: breakpoint-switch($bkpt, $media-string, true, $prfx, $base-font-size: $base-font-size);
|
||||
$moz-first: false;
|
||||
}
|
||||
@else {
|
||||
$moz: join($moz, breakpoint-switch($bkpt, $media-string, $prefix: $prfx, $base-font-size: $base-font-size));
|
||||
}
|
||||
}
|
||||
|
||||
@if $prfx == 'o' {
|
||||
@if $o-first {
|
||||
$o: breakpoint-switch($bkpt, $media-string, true, $prfx, $base-font-size: $base-font-size);
|
||||
$o-first: false;
|
||||
}
|
||||
@else {
|
||||
$o: join($o, breakpoint-switch($bkpt, $media-string, $prefix: $prfx, $base-font-size: $base-font-size));
|
||||
}
|
||||
}
|
||||
|
||||
@if $prfx == 'ms' {
|
||||
@if $ms-first {
|
||||
$ms: breakpoint-switch($bkpt, $media-string, true, $prfx, $base-font-size: $base-font-size);
|
||||
$ms-first: false;
|
||||
}
|
||||
@else {
|
||||
$ms: join($ms, breakpoint-switch($bkpt, $media-string, $prefix: $prfx, $base-font-size: $base-font-size));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@else {
|
||||
@each $bkpt in $breakpoint {
|
||||
@if $first == true {
|
||||
$query: breakpoint-switch($bkpt, $media-string, true, $base-font-size: $base-font-size);
|
||||
$first: false;
|
||||
}
|
||||
@else {
|
||||
$query: join($query, breakpoint-switch($bkpt, $media-string, $base-font-size: $base-font-size));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@if $breakpoint-no-queries {
|
||||
@if $no-query {
|
||||
$context: U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh('no queries', true);
|
||||
@if $breakpoint-no-query-wrappers and type-of($no-query) == string {
|
||||
#{$no-query} & {
|
||||
@content;
|
||||
$context: U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh('no query wrapper', $no-query);
|
||||
}
|
||||
}
|
||||
@else {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
}
|
||||
@else {
|
||||
@if $breakpoint-no-query-wrappers and type-of($no-query) == string {
|
||||
#{$no-query} & {
|
||||
@content;
|
||||
$context: U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh('no query wrapper', $no-query);
|
||||
}
|
||||
}
|
||||
@if $query {
|
||||
@media #{$query} {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
@else {
|
||||
$pf-queries: $webkit, $moz, $o, $ms;
|
||||
$pf-query: ();
|
||||
|
||||
@each $pfq in $pf-queries {
|
||||
@if $pfq {
|
||||
$pf-query: append($pf-query, $pfq, comma);
|
||||
}
|
||||
}
|
||||
@media #{$pf-query} {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include TXkgcmVzZXQhIEdvIGF3YXkh;
|
||||
}
|
||||
|
||||
@function breakpoint-switch($breakpoint, $media-string, $first: false, $prefix: false, $base-font-size: $breakpoint-base-font-size) {
|
||||
// Feature/Value/Length/Query Placehoders:
|
||||
$feature: false !default;
|
||||
$min-feature: "min-#{$breakpoint-default-pair}" !default;
|
||||
$max-feature: "max-#{$breakpoint-default-pair}" !default;
|
||||
$value: false !default;
|
||||
$min-value: false !default;
|
||||
$max-value: false !default;
|
||||
$length: false !default;
|
||||
$query: false !default;
|
||||
|
||||
$length: length($breakpoint);
|
||||
// Check to see if there is only one item.
|
||||
@if $length == 1 {
|
||||
$value: $breakpoint;
|
||||
@if type-of($breakpoint) == 'number' {
|
||||
$feature: $breakpoint-default-feature;
|
||||
}
|
||||
|
||||
// If EM Breakpoints are active, do it!
|
||||
@if $breakpoint-to-ems and type-of($value) == 'number' {
|
||||
$value: breakpoint-to-base-em($value, $base-font-size);
|
||||
}
|
||||
// Build the Query
|
||||
$query: breakpoint-generate($media-string, $feature, $value, $first);
|
||||
// Set Context
|
||||
$context: U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh($feature, $value);
|
||||
}
|
||||
@else if $length == 2 {
|
||||
// If both are numbers, we've got a double!
|
||||
@if type-of(nth($breakpoint, 1)) == 'number' and type-of(nth($breakpoint, 2)) == 'number' {
|
||||
// See which is larger.
|
||||
@if nth($breakpoint, 1) > nth($breakpoint, 2) {
|
||||
$min-value: nth($breakpoint, 2);
|
||||
$max-value: nth($breakpoint, 1);
|
||||
}
|
||||
@else {
|
||||
$min-value: nth($breakpoint, 1);
|
||||
$max-value: nth($breakpoint, 2);
|
||||
}
|
||||
|
||||
// If EM Breakpoints are active, do it!
|
||||
@if $breakpoint-to-ems and type-of($min-value) == 'number' {
|
||||
$min-value: breakpoint-to-base-em($min-value, $base-font-size);
|
||||
}
|
||||
@if $breakpoint-to-ems and type-of($max-value) == 'number' {
|
||||
$max-value: breakpoint-to-base-em($max-value, $base-font-size);
|
||||
}
|
||||
|
||||
// Min/Max for given
|
||||
$query: breakpoint-generate($media-string, $min-feature, $min-value, $first);
|
||||
$query: join($query, breakpoint-generate($media-string, $max-feature, $max-value));
|
||||
// Set Context
|
||||
$context: U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh($min-feature, $min-value);
|
||||
$context: U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh($max-feature, $max-value);
|
||||
}
|
||||
@else if type-of(nth($breakpoint, 1)) == 'string' and type-of(nth($breakpoint, 2)) == 'string' {
|
||||
@if breakpoint-string-value(nth($breakpoint, 1)) == true {
|
||||
$feature: nth($breakpoint, 1);
|
||||
$value: nth($breakpoint, 2);
|
||||
}
|
||||
@else {
|
||||
$feature: nth($breakpoint, 2);
|
||||
$value: nth($breakpoint, 1);
|
||||
}
|
||||
|
||||
// If EM Breakpoints are active, do it!
|
||||
@if $breakpoint-to-ems and type-of($value) == 'number' {
|
||||
$value: breakpoint-to-base-em($value, $base-font-size);
|
||||
}
|
||||
|
||||
// Build the Query
|
||||
$query: breakpoint-generate($media-string, $feature, $value, $first);
|
||||
// Set Context
|
||||
$context: U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh($feature, $value);
|
||||
}
|
||||
@else {
|
||||
// Because we can have either the first or second option be the feature, we switch on it.
|
||||
@if type-of(nth($breakpoint, 1)) == string {
|
||||
$feature: nth($breakpoint, 1);
|
||||
$value: nth($breakpoint, 2);
|
||||
}
|
||||
@else if type-of(nth($breakpoint, 2)) == string {
|
||||
$feature: nth($breakpoint, 2);
|
||||
$value: nth($breakpoint, 1);
|
||||
}
|
||||
|
||||
@if $feature == 'device-pixel-ratio' or $feature == 'min-device-pixel-ratio' or $feature == 'max-device-pixel-ratio' {
|
||||
$feature: breakpoint-experimental($feature, $prefix);
|
||||
//$value: 96 * $value * 1dpi;
|
||||
// @if $feature == 'device-pixel-ratio' {
|
||||
// $feature: 'resolution';
|
||||
// }
|
||||
// @else if $feature == 'min-device-pixel-ratio' {
|
||||
// $feature: 'min-resolution';
|
||||
// }
|
||||
// @else if $feature == 'max-device-pixel-ratio' {
|
||||
// $feature: 'max-resolution';
|
||||
// }
|
||||
}
|
||||
|
||||
// If EM Breakpoints are active, do it!
|
||||
@if $breakpoint-to-ems and type-of($value) == 'number' {
|
||||
$value: breakpoint-to-base-em($value, $base-font-size);
|
||||
}
|
||||
|
||||
// Build the Query
|
||||
$query: breakpoint-generate($media-string, $feature, $value, $first);
|
||||
// Set Context
|
||||
$context: U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh($feature, $value);
|
||||
}
|
||||
}
|
||||
@else if $length == 3 {
|
||||
@if type-of(nth($breakpoint, 1)) == 'string' {
|
||||
$feature: nth($breakpoint, 1);
|
||||
// See which is larger.
|
||||
@if nth($breakpoint, 2) > nth($breakpoint, 3) {
|
||||
$min-value: nth($breakpoint, 3);
|
||||
$max-value: nth($breakpoint, 2);
|
||||
}
|
||||
@else {
|
||||
$min-value: nth($breakpoint, 2);
|
||||
$max-value: nth($breakpoint, 3);
|
||||
}
|
||||
}
|
||||
@else {
|
||||
$feature: nth($breakpoint, 3);
|
||||
// See which is larger.
|
||||
@if nth($breakpoint, 1) > nth($breakpoint, 2) {
|
||||
$min-value: nth($breakpoint, 2);
|
||||
$max-value: nth($breakpoint, 1);
|
||||
}
|
||||
@else {
|
||||
$min-value: nth($breakpoint, 1);
|
||||
$max-value: nth($breakpoint, 2);
|
||||
}
|
||||
}
|
||||
|
||||
// If EM Breakpoints are active, do it!
|
||||
@if $breakpoint-to-ems and type-of($min-value) == 'number' {
|
||||
$min-value: breakpoint-to-base-em($min-value, $base-font-size);
|
||||
}
|
||||
@if $breakpoint-to-ems and type-of($max-value) == 'number' {
|
||||
$max-value: breakpoint-to-base-em($max-value, $base-font-size);
|
||||
}
|
||||
|
||||
@if breakpoint-min-max($feature) == true {
|
||||
@if $feature == 'device-pixel-ratio' {
|
||||
$min-feature: breakpoint-experimental('min-#{$feature}', $prefix);
|
||||
$max-feature: breakpoint-experimental('max-#{$feature}', $prefix);
|
||||
}
|
||||
@else {
|
||||
$min-feature: 'min-#{$feature}';
|
||||
$max-feature: 'max-#{$feature}';
|
||||
}
|
||||
|
||||
// Min/Max for given
|
||||
$query: breakpoint-generate($media-string, $min-feature, $min-value, $first);
|
||||
$query: join($query, breakpoint-generate($media-string, $max-feature, $max-value));
|
||||
// Set Context
|
||||
$context: U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh($min-feature, $min-value);
|
||||
$context: U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh($max-feature, $max-value);
|
||||
}
|
||||
@else {
|
||||
@warn '#{$feature} cannot have a min/max value!';
|
||||
}
|
||||
}
|
||||
|
||||
@return $query;
|
||||
}
|
||||
|
||||
@function breakpoint-generate($media, $feature, $value, $first: false) {
|
||||
// Media Query string to be returned
|
||||
$new-string: "";
|
||||
|
||||
// If it's the first item, it gets special treatment
|
||||
@if $first == true {
|
||||
// And Statement
|
||||
$and: 'and ';
|
||||
// If $media is blank (i.e. all), remove and statement
|
||||
@if $media == '' {
|
||||
$and: '';
|
||||
}
|
||||
|
||||
@if $feature != false {
|
||||
$new-string: #{$media}unquote("#{$and}(#{$feature}: #{$value})");
|
||||
}
|
||||
@else {
|
||||
$new-string: #{$media}unquote("#{$and}(#{$value})");
|
||||
}
|
||||
}
|
||||
|
||||
@else {
|
||||
@if $feature != false {
|
||||
$new-string: unquote("and (#{$feature}: #{$value})");
|
||||
}
|
||||
@else {
|
||||
$new-string: unquote("and (#{$value})");
|
||||
}
|
||||
}
|
||||
|
||||
@return $new-string;
|
||||
}
|
354
core/admin/assets/sass/modules/forms.scss
Normal file
@ -0,0 +1,354 @@
|
||||
/*
|
||||
* These are the global generic form styles used throughout the Ghost admin,
|
||||
* but mainly in the settings pages. Don't fuck with them.
|
||||
*
|
||||
* Table of Contents:
|
||||
*
|
||||
* General
|
||||
* Buttons
|
||||
* Split Buttons
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
General
|
||||
============================================================================= */
|
||||
|
||||
form {
|
||||
|
||||
fieldset {
|
||||
border: none;
|
||||
margin:0 0 3em 0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
legend {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin: 2em 0;
|
||||
border-bottom:$lightbrown 1px solid;
|
||||
font-size: 1.2em;
|
||||
line-height: 2.0em;
|
||||
color: $brown;
|
||||
}
|
||||
|
||||
label {
|
||||
display:block;
|
||||
margin:1.5em 0;
|
||||
padding-left:140px;
|
||||
position:relative;
|
||||
|
||||
b {
|
||||
display:inline-block;
|
||||
position: absolute;
|
||||
top:0.5em;
|
||||
left:0;
|
||||
width:120px;
|
||||
font-weight:normal;
|
||||
color:$darkgrey;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
color: darken($brown, 5%);
|
||||
font-size: 1em;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
input, textarea, select {
|
||||
width: 260px;
|
||||
padding: 5px 7px;
|
||||
margin: 0;
|
||||
outline: 0;
|
||||
font-size: 1.1em;
|
||||
line-height: 1.4em;
|
||||
background: #fff;
|
||||
border: darken($lightbrown, 5%) 1px solid;
|
||||
@include border-radius;
|
||||
@include transition;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width:100%;
|
||||
max-width:340px;
|
||||
min-width:250px;
|
||||
height:auto;
|
||||
min-height: 80px;
|
||||
}
|
||||
|
||||
input, select, textarea {
|
||||
margin-bottom:5px;
|
||||
}
|
||||
|
||||
input[type="text"]:focus,
|
||||
input[type="email"]:focus,
|
||||
input[type="search"]:focus,
|
||||
input[type="tel"]:focus,
|
||||
input[type="url"]:focus,
|
||||
input[type="password"]:focus,
|
||||
input[type="number"]:focus,
|
||||
input[type="date"]:focus,
|
||||
input[type="month"]:focus,
|
||||
input[type="week"]:focus,
|
||||
input[type="time"]:focus,
|
||||
input[type="datetime"]:focus,
|
||||
input[type="datetime-local"]:focus,
|
||||
textarea:focus {
|
||||
border:$grey 1px solid;
|
||||
background:#fff;
|
||||
outline:none;
|
||||
outline-width:0;
|
||||
@include transition;
|
||||
}
|
||||
|
||||
select {
|
||||
width:270px;
|
||||
height:30px;
|
||||
line-height:30px;
|
||||
}
|
||||
|
||||
.radio input[type="radio"],
|
||||
.checkbox input[type="checkbox"] {
|
||||
float: left;
|
||||
width:auto;
|
||||
margin-right:6px;
|
||||
margin-top:4px;
|
||||
font-size:1em;
|
||||
}
|
||||
|
||||
.radio, .checkbox {
|
||||
width:auto;
|
||||
margin: 5px 0;
|
||||
font-weight: normal;
|
||||
padding:0.55em 0;
|
||||
}
|
||||
|
||||
}//form
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Buttons
|
||||
============================================================================= */
|
||||
|
||||
/*
|
||||
* Buttons are used for primary calls to action on a page.
|
||||
*
|
||||
* Usage:
|
||||
* <button type="button" class="button">Default</button>
|
||||
*/
|
||||
|
||||
// This base style is used on all buttons
|
||||
%button {
|
||||
@include box-sizing(border-box);
|
||||
min-height: 35px;
|
||||
width:auto;
|
||||
display: inline-block;
|
||||
padding: 0.9em 1.37em;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
font-size: 11px; // Hack because Firefox sucks ass.
|
||||
line-height: 13px; // Hack because Firefox sucks ass.
|
||||
font-weight: 300;
|
||||
text-align: center;
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
text-shadow: none;
|
||||
@include border-radius(0.2em);
|
||||
border: rgba(0,0,0,0.05) 0.1em solid;
|
||||
@include transition(background 0.3s ease, border-color 0.3s ease);
|
||||
|
||||
&:hover {
|
||||
border-color: transparent;
|
||||
background: #f8f8f8;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
// This is the default button style
|
||||
.button,
|
||||
button,
|
||||
input[type="button"] {
|
||||
@extend %button;
|
||||
color:#777;
|
||||
font-weight: normal;
|
||||
background: #eee;
|
||||
@include box-shadow(none);
|
||||
&:hover {
|
||||
border-color: rgba(0,0,0,0.1);
|
||||
}
|
||||
}
|
||||
|
||||
// Button for save/next/continue/confirm actions
|
||||
.button-save,
|
||||
button[type="submit"],
|
||||
input[type="submit"] {
|
||||
@extend %button;
|
||||
background: $blue;
|
||||
@include box-shadow(none);
|
||||
&:hover {background: darken($blue, 10%);}
|
||||
}
|
||||
|
||||
// Button for actions which add stuff
|
||||
.button-add {
|
||||
@extend %button;
|
||||
background: $green;
|
||||
&:hover {background: darken($green, 8%);}
|
||||
}
|
||||
|
||||
// Button for deleting/removing stuff
|
||||
.button-delete,
|
||||
button[type="reset"],
|
||||
input[type="reset"] {
|
||||
@extend %button;
|
||||
background: $red;
|
||||
@include box-shadow(none);
|
||||
&:hover {background: darken($red, 10%);}
|
||||
}
|
||||
|
||||
// Alternative button with more visual attention, but no extra semantic meaning
|
||||
.button-alt {
|
||||
@extend %button;
|
||||
background: lighten($darkgrey, 10%);
|
||||
&:hover {background: $darkgrey;}
|
||||
}
|
||||
|
||||
// This applies normal link styles to de-emphasise a button
|
||||
.button-link {
|
||||
@extend %button;
|
||||
color: $blue;
|
||||
background: transparent;
|
||||
border: none;
|
||||
&:hover {
|
||||
background: transparent;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Split Buttons
|
||||
============================================================================= */
|
||||
|
||||
/*
|
||||
* The splitbutton adds addition values to a button, via a dropdown (or drop-up).
|
||||
*
|
||||
* Usage:
|
||||
* <section class="splitbutton">
|
||||
* <button type="button" class="button">Split Up</button>
|
||||
* <a class="options" href="#"><span class="hidden">Options</span></a>
|
||||
* </section>
|
||||
*/
|
||||
|
||||
// These are the base styles applied to all splitbuttons
|
||||
%splitbutton {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
font-size: 0; // hack to stop space after button
|
||||
white-space: nowrap;
|
||||
|
||||
button {
|
||||
font-size: 11px; // hack to restore font size
|
||||
@include border-top-right-radius(0);
|
||||
@include border-bottom-right-radius(0);
|
||||
}
|
||||
|
||||
// This is the additional dropdown arrow, to the right of the button.
|
||||
.options {
|
||||
display: inline-block;
|
||||
position:relative;
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
margin-left: -1px;
|
||||
vertical-align: top;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
background: #e5e5e5;
|
||||
@include border-radius(0 2px 2px 0);
|
||||
@include box-shadow(
|
||||
rgba(0,0,0,0.02) 0 1px 0 inset,
|
||||
rgba(0,0,0,0.02) -1px 0 0 inset,
|
||||
rgba(0,0,0,0.02) 0 -1px 0 inset
|
||||
);
|
||||
@include icon($i-chevron-down, 9px) {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 50%;
|
||||
margin-top: -3px;
|
||||
margin-right: -5px;
|
||||
@include transition(transform 0.3s ease, margin-top 0.3s ease);
|
||||
};
|
||||
|
||||
// Spin the arrow on hover
|
||||
&:hover {
|
||||
@include box-shadow(none);
|
||||
background: #f8f8f8;
|
||||
@include icon($i-chevron-down) {
|
||||
@include transform(rotate(360deg));
|
||||
};
|
||||
}
|
||||
|
||||
// If it has a class of "up" spin it an extra 180degress to point up
|
||||
&.up:hover {
|
||||
@include icon($i-chevron-down) {
|
||||
margin-top:-4px;
|
||||
@include transform(rotate(540deg));
|
||||
@include transition(transform 0.6s ease);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The default splitbutton
|
||||
.splitbutton {
|
||||
@extend %splitbutton;
|
||||
.options {
|
||||
color:#777;
|
||||
&:hover {
|
||||
@include box-shadow(
|
||||
rgba(0,0,0,0.07) 0 1px 0 inset,
|
||||
rgba(0,0,0,0.07) -1px 0 0 inset,
|
||||
rgba(0,0,0,0.07) 0 -1px 0 inset
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For save/next/continue/confirm actions
|
||||
.splitbutton-save {
|
||||
@extend %splitbutton;
|
||||
.options {
|
||||
background: darken($blue, 5%);
|
||||
&:hover {background: darken($blue, 10%);}
|
||||
}
|
||||
}
|
||||
|
||||
// For actions which add something
|
||||
.splitbutton-add {
|
||||
@extend %splitbutton;
|
||||
.options {
|
||||
background: darken($green, 6%);
|
||||
&:hover {background: darken($green, 8%);}
|
||||
}
|
||||
}
|
||||
|
||||
// For actions which delete something
|
||||
.splitbutton-delete {
|
||||
@extend %splitbutton;
|
||||
.options {
|
||||
background: darken($red, 6%);
|
||||
&:hover {background: darken($red, 10%);}
|
||||
}
|
||||
}
|
||||
|
||||
// Alternative style with more visual attention, but no extra semantic meaning
|
||||
.splitbutton-alt {
|
||||
@extend %splitbutton;
|
||||
.options {
|
||||
background: lighten($darkgrey, 4%);
|
||||
&:hover {background: $darkgrey;}
|
||||
}
|
||||
}
|
||||
|
1137
core/admin/assets/sass/modules/global.scss
Normal file
128
core/admin/assets/sass/modules/grid.scss
Normal file
@ -0,0 +1,128 @@
|
||||
.container {
|
||||
margin: auto;
|
||||
padding: 0 15px;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
/* 18 Column Grid
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Span 1: 3.66666666667%
|
||||
Span 2: 9.33333333333%
|
||||
Span 3: 15.0%
|
||||
Span 4: 20.6666666667%
|
||||
Span 5: 26.3333333333%
|
||||
Span 6: 32.0%
|
||||
Span 7: 37.6666666667%
|
||||
Span 8: 43.3333333333%
|
||||
Span 9: 49.0%
|
||||
Span 10: 54.6666666667%
|
||||
Span 11: 60.3333333333%
|
||||
Span 12: 66.0%
|
||||
Span 13: 71.6666666667%
|
||||
Span 14: 77.3333333333%
|
||||
Span 15: 83.0%
|
||||
Span 16: 88.6666666667%
|
||||
Span 17: 94.3333333333%
|
||||
Span 18: 100%
|
||||
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/* --- Grid variables ---*/
|
||||
$max_columns: 8;
|
||||
$gutter: 2%;
|
||||
|
||||
.row {
|
||||
width: 100%;
|
||||
*zoom: 1;
|
||||
position: relative;
|
||||
}
|
||||
.row [class*="span"] {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
.row {
|
||||
margin-left: -15px;
|
||||
}
|
||||
.span1, .span2, .span3, .span4 {
|
||||
width: 50%;
|
||||
float: left;
|
||||
padding-left: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 1200px) {
|
||||
|
||||
@mixin span($num, $gutter, $max_columns) {
|
||||
$one_col: (100% - ($gutter * ($max_columns - 1))) / $max_columns;
|
||||
width:($one_col * $num) + ($gutter * ($num - 1));
|
||||
margin-left:$gutter;
|
||||
float: left;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@mixin span_first {
|
||||
margin-left:0;
|
||||
}
|
||||
.row {
|
||||
margin-left: 0;
|
||||
}
|
||||
.row:before,
|
||||
.row:after {
|
||||
display: table;
|
||||
line-height: 0;
|
||||
content: "";
|
||||
}
|
||||
.row:after {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.row [class*="span"] {
|
||||
margin-bottom: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
.row [class*="span"].bottom-margin {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.row [class*="span"]:first-child {
|
||||
@include span_first;
|
||||
}
|
||||
|
||||
.span1 {
|
||||
@include span(1, $gutter, $max_columns);
|
||||
}
|
||||
.span2 {
|
||||
@include span(2, $gutter, $max_columns);
|
||||
}
|
||||
.span3 {
|
||||
@include span(3, $gutter, $max_columns);
|
||||
}
|
||||
.span4 {
|
||||
@include span(4, $gutter, $max_columns);
|
||||
}
|
||||
.span5 {
|
||||
@include span(5, $gutter, $max_columns);
|
||||
}
|
||||
.span6 {
|
||||
@include span(6, $gutter, $max_columns);
|
||||
}
|
||||
.span7 {
|
||||
@include span(7, $gutter, $max_columns);
|
||||
}
|
||||
.span8 {
|
||||
@include span_first;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.offset1 {
|
||||
margin-left: 5.66666666667%;
|
||||
}
|
||||
.offset2 {
|
||||
margin-left: 11.33333333333%;
|
||||
}
|
||||
|
||||
}
|
207
core/admin/assets/sass/modules/icons.scss
Normal file
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* The icons used in Ghost are the Pictos set by Drew Wilson - http://pictos.css
|
||||
* They are embedded via a custom icon font built with http://icomoon.io
|
||||
*
|
||||
* Table of Contents:
|
||||
*
|
||||
* Font Face
|
||||
* Icon Element
|
||||
* Icon Variables / Short Names
|
||||
* Usage
|
||||
*/
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
The Font Face
|
||||
============================================================================= */
|
||||
|
||||
/* Generated by icomoon.co */
|
||||
|
||||
@font-face {
|
||||
font-family: 'Icons';
|
||||
src:url('../fonts/icons.eot');
|
||||
src:url('../fonts/icons.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/icons.woff') format('woff'),
|
||||
url('../fonts/icons.ttf') format('truetype'),
|
||||
url('../fonts/icons.svg#icons') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
The Icon Element
|
||||
============================================================================= */
|
||||
|
||||
/*
|
||||
* Epic dynamic icon element by Eric Eggert, this thing is so fucking cool it's
|
||||
* actually unreal. http://cl.ly/O40t
|
||||
*/
|
||||
|
||||
%icon:before,
|
||||
%icon:after {
|
||||
font-family: "Icons";
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
vertical-align: -7%;
|
||||
text-transform:none;
|
||||
speak: none;
|
||||
line-height: 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
|
||||
}
|
||||
|
||||
@mixin icon($char, $size: '', $color: '') {
|
||||
@extend %icon;
|
||||
|
||||
&:before {
|
||||
content: '#{$char}';
|
||||
@if $size != '' {
|
||||
font-size: $size;
|
||||
}
|
||||
@if $color != '' {
|
||||
color: $color;
|
||||
}
|
||||
@content;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
text-decoration:none;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Special use case for when we want to add an icon after an element rather
|
||||
* than before it. For things like dropdowns.
|
||||
*/
|
||||
|
||||
@mixin icon-after($char, $size: '', $color: '') {
|
||||
@extend %icon;
|
||||
|
||||
&:after {
|
||||
content: '#{$char}';
|
||||
@if $size != '' {
|
||||
font-size: $size;
|
||||
}
|
||||
@if $color != '' {
|
||||
color: $color;
|
||||
}
|
||||
@content;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
text-decoration:none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Icon Variables / Short Names
|
||||
============================================================================= */
|
||||
|
||||
/*
|
||||
* For accessibility, icon characters in the icon font are stored in Unicode's
|
||||
* Private Use Area characters. This means that screen readers won't attempt to
|
||||
* read them out loud. For code maintainability, we then store these Unicode
|
||||
* references inside Sass variables.
|
||||
*/
|
||||
|
||||
$i-ghost: \e000;
|
||||
$i-chevron-down: \e001;
|
||||
$i-users: \e002;
|
||||
$i-tag: \e003;
|
||||
$i-tablet: \e004;
|
||||
$i-menu: \e005;
|
||||
$i-settings: \e006;
|
||||
$i-search: \e007;
|
||||
$i-search-left: \e008;
|
||||
$i-rss: \e009;
|
||||
$i-preview: \e00a;
|
||||
$i-plugins: \e00b;
|
||||
$i-pin: \e00c;
|
||||
$i-pc: \e00d;
|
||||
$i-pacman: \e00e;
|
||||
$i-edit: \e00f;
|
||||
$i-mobile: \e010;
|
||||
$i-image: \e011;
|
||||
$i-mail: \e012;
|
||||
$i-list: \e013;
|
||||
$i-info: \e014;
|
||||
$i-home: \e015;
|
||||
$i-grid: \e016;
|
||||
$i-fullscreen: \e017;
|
||||
$i-question: \e018;
|
||||
$i-external: \e019;
|
||||
$i-error: \e01a;
|
||||
$i-comments: \e01b;
|
||||
$i-close: \e01c;
|
||||
$i-chevron: \e01d;
|
||||
$i-calendar: \e01e;
|
||||
$i-archive: \e01f;
|
||||
$i-services: \e020;
|
||||
$i-appearance: \e021;
|
||||
$i-video: \e022;
|
||||
$i-remove: \e023;
|
||||
$i-----: \e024;
|
||||
$i-stats: \e025;
|
||||
$i-featured: \e026;
|
||||
$i-unfeatured: \e027;
|
||||
$i-clock: \e028;
|
||||
$i-settings2: \e029;
|
||||
$i-camera: \e02a;
|
||||
$i-power: \e02b;
|
||||
$i-lock: \e02c;
|
||||
$i-content: \e02d;
|
||||
$i-user: \e02e;
|
||||
$i-support: \e02f;
|
||||
$i-success: \e030;
|
||||
$i-notification: \e031;
|
||||
$i-add: \e032;
|
||||
$i-check: \e033;
|
||||
$i-x: \e034;
|
||||
$i-link: \e035;
|
||||
$i-camera: \e036;
|
||||
|
||||
// Placeholder
|
||||
$i: \e018;
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Usage
|
||||
=============================================================================
|
||||
|
||||
To create a button with a label that is prefixed with a camera icon, we might
|
||||
write our Sass something like this:
|
||||
|
||||
#button {
|
||||
display: block;
|
||||
width: 200px;
|
||||
height: 40px;
|
||||
@include icon($i-camera, 16px, #fff) {vertical-align:-10%;};
|
||||
}
|
||||
|
||||
Thi would then output full CSS something like this:
|
||||
|
||||
#button {
|
||||
display: block;
|
||||
width: 200px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
#button:before {
|
||||
content: "\e02a";
|
||||
size: 16px;
|
||||
color: #fff;
|
||||
font-family: "Icons";
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
vertical-align: -10%;
|
||||
text-transform:none;
|
||||
speak: none;
|
||||
line-height: 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
186
core/admin/assets/sass/modules/mixins.scss
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* These are Sass variables used to make our CSS more dynamic by re-using
|
||||
* common property values throughout our styles. Don't overdo it.
|
||||
*
|
||||
* Table of Contents:
|
||||
*
|
||||
* Compass Shit
|
||||
* Compass Plugins
|
||||
* Colors
|
||||
* Gradients
|
||||
* Typography
|
||||
* Global Styles
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Compass Imports
|
||||
============================================================================= */
|
||||
|
||||
// Compass - http://compass-style.org/
|
||||
@import "compass";
|
||||
$default-border-radius: 2px;
|
||||
$default-box-shadow-color: rgba(0,0,0,0.05);
|
||||
$default-box-shadow-v-offset: 1px;
|
||||
$default-transition-duration: 0.3s;
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Compass Plugins
|
||||
============================================================================= */
|
||||
|
||||
// Breakpoint - http://breakpoint-sass.com/
|
||||
@import "breakpoint";
|
||||
$breakpoint-default-feature: max-width;
|
||||
|
||||
// Max widths
|
||||
$netbook: 1000px;
|
||||
$tablet: 800px;
|
||||
$mobile: 400px;
|
||||
|
||||
// Min widths
|
||||
$biggerthan-widescreen: min-width 1500px, min-width 1500px;
|
||||
$biggerthan-netbook: min-width 1000px, min-width 1000px;
|
||||
$biggerthan-tablet: min-width 800px, min-width 800px;
|
||||
$biggerthan-mobile: min-width 400px, min-width 400px;
|
||||
|
||||
// Heights
|
||||
$letterbox: max-height 600px, max-height 600px;
|
||||
|
||||
// Pixel Densities
|
||||
$retina: 2 device-pixel-ratio;
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Colors
|
||||
============================================================================= */
|
||||
|
||||
$darkgrey: #242628;
|
||||
$grey: #35393b;
|
||||
$midgrey: #7d878a;
|
||||
$lightgrey: #e2edf2;
|
||||
|
||||
$brown: #aaa9a2;
|
||||
$midbrown: #c0bfb6;
|
||||
$lightbrown: #edece4;
|
||||
|
||||
$blue: #5BA4E5;
|
||||
$red: #e25440;
|
||||
$orange: #F2A925;
|
||||
$green: #9FBB58;
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Gradients
|
||||
============================================================================= */
|
||||
|
||||
/*
|
||||
* Auto Gradients
|
||||
*
|
||||
* If the gradient mixin is called with 1 value: gradient(#444) - then a second
|
||||
* color which is 10% lighter than the entered value will be auto-generated. If
|
||||
* the gradient mixin is called with 2 values: gradient(#444,#666) - then those
|
||||
* two values will be used instead, as normal.
|
||||
*/
|
||||
|
||||
@mixin gradient($color1: #aaa, $color2: none) {
|
||||
|
||||
@if $color2 == 'none' {
|
||||
background-color: lighten($color1, 10%);
|
||||
background-image: -webkit-linear-gradient(bottom, $color1, lighten($color1, 10%));
|
||||
background-image: -moz-linear-gradient(bottom, $color1, lighten($color1, 10%));
|
||||
background-image: -ms-linear-gradient(bottom, $color1, lighten($color1, 10%));
|
||||
background-image: linear-gradient(bottom, $color1, lighten($color1, 10%));
|
||||
@include box-shadow(rgba(0,0,0,0.2) 0 -1px 0 inset, rgba(0,0,0,0.1) 0 1px 0 inset);
|
||||
} @else {
|
||||
background-color: $color2;
|
||||
background-image: -webkit-linear-gradient(bottom, $color1, $color2);
|
||||
background-image: -moz-linear-gradient(bottom, $color1, $color2);
|
||||
background-image: -ms-linear-gradient(bottom, $color1, $color2);
|
||||
background-image: linear-gradient(to top, $color1, $color2);
|
||||
@include box-shadow(rgba(0,0,0,0.2) 0 -1px 0 inset, rgba(0,0,0,0.1) 0 1px 0 inset);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// The same as the above, but with the colours reversed.
|
||||
|
||||
@mixin inversegradient($color1: #aaa, $color2: none) {
|
||||
|
||||
@if $color2 == 'none' {
|
||||
background-color: $color1;
|
||||
background-image: -webkit-linear-gradient(bottom, lighten($color1, 10%), $color1);
|
||||
background-image: -moz-linear-gradient(bottom, lighten($color1, 10%), $color1);
|
||||
background-image: -ms-linear-gradient(bottom, lighten($color1, 10%), $color1);
|
||||
background-image: linear-gradient(bottom, lighten($color1, 10%), $color1);
|
||||
@include box-shadow(rgba(0,0,0,0.2) 0 -1px 0 inset, rgba(0,0,0,0.1) 0 1px 0 inset);
|
||||
} @else {
|
||||
background-color: $color1;
|
||||
background-image: -webkit-linear-gradient(bottom, $color2, $color1);
|
||||
background-image: -moz-linear-gradient(bottom, $color2, $color1);
|
||||
background-image: -ms-linear-gradient(bottom, $color2, $color1);
|
||||
background-image: linear-gradient(to top, $color2, $color1);
|
||||
@include box-shadow(rgba(0,0,0,0.2) 0 -1px 0 inset, rgba(0,0,0,0.1) 0 1px 0 inset);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Typography
|
||||
============================================================================= */
|
||||
|
||||
@mixin baseline {
|
||||
margin: 1.6em 0;
|
||||
}
|
||||
|
||||
//Does this really need to be a mixin?
|
||||
@mixin hidden {
|
||||
text-indent: -9999px;
|
||||
visibility: hidden;
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Global Elements
|
||||
============================================================================= */
|
||||
|
||||
%box, .box {
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
background: #fff;
|
||||
position: relative;
|
||||
@include box-shadow;
|
||||
|
||||
header {
|
||||
height:14px;
|
||||
border-bottom: 1px solid $lightbrown;
|
||||
padding-bottom: 15px;
|
||||
margin-bottom: 15px;
|
||||
text-transform: uppercase;
|
||||
font-size:0.85em;
|
||||
color: $brown;
|
||||
}
|
||||
|
||||
footer {
|
||||
height:14px;
|
||||
border-top: 1px solid $lightbrown;
|
||||
padding-top: 10px;
|
||||
margin-top:15px;
|
||||
text-transform: uppercase;
|
||||
font-size:0.85em;
|
||||
color: $brown;
|
||||
}
|
||||
|
||||
header a,
|
||||
footer a {
|
||||
color:$brown;
|
||||
|
||||
&:hover {
|
||||
color:$darkgrey;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
396
core/admin/assets/sass/modules/normalize.scss
vendored
Normal file
@ -0,0 +1,396 @@
|
||||
/*! normalize.css v2.1.0 | MIT License | git.io/normalize */
|
||||
|
||||
/* ==========================================================================
|
||||
HTML5 display definitions
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Correct `block` display not defined in IE 8/9.
|
||||
*/
|
||||
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
main,
|
||||
nav,
|
||||
section,
|
||||
summary {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct `inline-block` display not defined in IE 8/9.
|
||||
*/
|
||||
|
||||
audio,
|
||||
canvas,
|
||||
video {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent modern browsers from displaying `audio` without controls.
|
||||
* Remove excess height in iOS 5 devices.
|
||||
*/
|
||||
|
||||
audio:not([controls]) {
|
||||
display: none;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address styling not present in IE 8/9.
|
||||
*/
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Base
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* 1. Set default font family to sans-serif.
|
||||
* 2. Prevent iOS text size adjust after orientation change, without disabling
|
||||
* user zoom.
|
||||
*/
|
||||
|
||||
html {
|
||||
font-family: sans-serif; /* 1 */
|
||||
-webkit-text-size-adjust: 100%; /* 2 */
|
||||
-ms-text-size-adjust: 100%; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove default margin.
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Links
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Address `outline` inconsistency between Chrome and other browsers.
|
||||
*/
|
||||
|
||||
a:focus {
|
||||
outline: thin dotted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Improve readability when focused and also mouse hovered in all browsers.
|
||||
*/
|
||||
|
||||
a:active,
|
||||
a:hover {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Typography
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Address variable `h1` font-size and margin within `section` and `article`
|
||||
* contexts in Firefox 4+, Safari 5, and Chrome.
|
||||
*/
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address styling not present in IE 8/9, Safari 5, and Chrome.
|
||||
*/
|
||||
|
||||
abbr[title] {
|
||||
border-bottom: 1px dotted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
|
||||
*/
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address styling not present in Safari 5 and Chrome.
|
||||
*/
|
||||
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address differences between Firefox and other browsers.
|
||||
*/
|
||||
|
||||
hr {
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address styling not present in IE 8/9.
|
||||
*/
|
||||
|
||||
mark {
|
||||
background: #ff0;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct font family set oddly in Safari 5 and Chrome.
|
||||
*/
|
||||
|
||||
code,
|
||||
kbd,
|
||||
pre,
|
||||
samp {
|
||||
font-family: monospace, serif;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
/**
|
||||
* Improve readability of pre-formatted text in all browsers.
|
||||
*/
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set consistent quote types.
|
||||
*/
|
||||
|
||||
q {
|
||||
quotes: "\201C" "\201D" "\2018" "\2019";
|
||||
}
|
||||
|
||||
/**
|
||||
* Address inconsistent and variable font size in all browsers.
|
||||
*/
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent `sub` and `sup` affecting `line-height` in all browsers.
|
||||
*/
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Embedded content
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove border when inside `a` element in IE 8/9.
|
||||
*/
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct overflow displayed oddly in IE 9.
|
||||
*/
|
||||
|
||||
svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Figures
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Address margin not present in IE 8/9 and Safari 5.
|
||||
*/
|
||||
|
||||
figure {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Forms
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Define consistent border, margin, and padding.
|
||||
*/
|
||||
|
||||
fieldset {
|
||||
border: 1px solid #c0c0c0;
|
||||
margin: 0 2px;
|
||||
padding: 0.35em 0.625em 0.75em;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct `color` not being inherited in IE 8/9.
|
||||
* 2. Remove padding so people aren't caught out if they zero out fieldsets.
|
||||
*/
|
||||
|
||||
legend {
|
||||
border: 0; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct font family not being inherited in all browsers.
|
||||
* 2. Correct font size not being inherited in all browsers.
|
||||
* 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.
|
||||
*/
|
||||
|
||||
button,
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit; /* 1 */
|
||||
font-size: 100%; /* 2 */
|
||||
margin: 0; /* 3 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Address Firefox 4+ setting `line-height` on `input` using `!important` in
|
||||
* the UA stylesheet.
|
||||
*/
|
||||
|
||||
button,
|
||||
input {
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address inconsistent `text-transform` inheritance for `button` and `select`.
|
||||
* All other form control elements do not inherit `text-transform` values.
|
||||
* Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+.
|
||||
* Correct `select` style inheritance in Firefox 4+ and Opera.
|
||||
*/
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
|
||||
* and `video` controls.
|
||||
* 2. Correct inability to style clickable `input` types in iOS.
|
||||
* 3. Improve usability and consistency of cursor style between image-type
|
||||
* `input` and others.
|
||||
*/
|
||||
|
||||
button,
|
||||
html input[type="button"], /* 1 */
|
||||
input[type="reset"],
|
||||
input[type="submit"] {
|
||||
-webkit-appearance: button; /* 2 */
|
||||
cursor: pointer; /* 3 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-set default cursor for disabled elements.
|
||||
*/
|
||||
|
||||
button[disabled],
|
||||
html input[disabled] {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Address box sizing set to `content-box` in IE 8/9.
|
||||
* 2. Remove excess padding in IE 8/9.
|
||||
*/
|
||||
|
||||
input[type="checkbox"],
|
||||
input[type="radio"] {
|
||||
box-sizing: border-box; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.
|
||||
* 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome
|
||||
* (include `-moz` to future-proof).
|
||||
*/
|
||||
|
||||
input[type="search"] {
|
||||
-webkit-appearance: textfield; /* 1 */
|
||||
-moz-box-sizing: content-box;
|
||||
-webkit-box-sizing: content-box; /* 2 */
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove inner padding and search cancel button in Safari 5 and Chrome
|
||||
* on OS X.
|
||||
*/
|
||||
|
||||
input[type="search"]::-webkit-search-cancel-button,
|
||||
input[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove inner padding and border in Firefox 4+.
|
||||
*/
|
||||
|
||||
button::-moz-focus-inner,
|
||||
input::-moz-focus-inner {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Remove default vertical scrollbar in IE 8/9.
|
||||
* 2. Improve readability and alignment in all browsers.
|
||||
*/
|
||||
|
||||
textarea {
|
||||
overflow: auto; /* 1 */
|
||||
vertical-align: top; /* 2 */
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Tables
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove most spacing between table cells.
|
||||
*/
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
678
core/admin/assets/sass/modules/typeplate.scss
Normal file
@ -0,0 +1,678 @@
|
||||
/*!
|
||||
+---------------------------------------------------------------------+
|
||||
| _ _ _ |
|
||||
| | |_ _ _ _ __ ___ _ __ | | __ _ | |_ ___ |
|
||||
| | __|| | | || '_ \ / _ \| '_ \ | | / _` || __|/ _ \ |
|
||||
| | |_ | |_| || |_) || __/| |_) || || (_| || |_| __/ |
|
||||
| \__| \__, || .__/ \___|| .__/ |_| \__,_| \__|\___| |
|
||||
| |___/ |_| |_| |
|
||||
| |
|
||||
| |
|
||||
| URL: http://typeplate.com |
|
||||
| VERSION: 1.0.0 |
|
||||
| Github: https://github.com/typePlate/typeplate.github.com |
|
||||
| AUTHORS: Zachary Kain (@zakkain) & Dennis Gaebel (@gryghostvisuals) |
|
||||
| LICENSE: Creative Commmons |
|
||||
| http://creativecommons.org/licenses/by/3.0 |
|
||||
| |
|
||||
+---------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
|
||||
// ==========================================================================
|
||||
//
|
||||
// $V a r i a b l e s
|
||||
//
|
||||
// ==========================================================================
|
||||
|
||||
|
||||
// $B a s e T y p e
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
$weight: normal;
|
||||
$line-height: 1.65;
|
||||
$font-size: 81.2; // percentage value (16 * 112.5% = 18px)
|
||||
$font-base: 16 * ($font-size/100); // converts our percentage to a pixel value
|
||||
$measure: $font-base * $line-height;
|
||||
$font-family: Lato, sans-serif;
|
||||
$font-family-serif: serif;
|
||||
$font-family-mono: Inconsolata, monospace;
|
||||
$font-properties: $weight, $line-height, $font-size, $font-family;
|
||||
|
||||
//the serif boolean var can be redeclared from another stylesheet. However
|
||||
//the var must be placed after your @import "typeplate.scss";
|
||||
$sans-serif-boolean: true !default;
|
||||
|
||||
|
||||
// $C o l o r
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
$body-copy-color: #444;
|
||||
$heading-color: #222;
|
||||
|
||||
|
||||
// $A M P E R S A N D @font-face
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
$amp-fontface-name: Ampersand;
|
||||
$amp-fontface-source: local('Georgia'), local('Garamond'), local('Palatino'), local('Book Antiqua');
|
||||
$amp-fontface-fallback: local('Georgia');
|
||||
|
||||
|
||||
// $A M P E R S A N D e l e m e n t
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
// Allows for our ampersand element to have differing
|
||||
// font-family from the ampersand unicode font-family.
|
||||
$amp-font-family: Verdana, sans-serif;
|
||||
|
||||
|
||||
// $T y p e S c a l e
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
$tera: 117; // 117 = 18 × 6.5
|
||||
$giga: 90; // 90 = 18 × 5
|
||||
$mega: 72; // 72 = 18 × 4
|
||||
$alpha: 60; // 60 = 18 × 3.3333
|
||||
$beta: 48; // 48 = 18 × 2.6667
|
||||
$gamma: 36; // 36 = 18 × 2
|
||||
$delta: 24; // 24 = 18 × 1.3333
|
||||
$epsilon: 21; // 21 = 18 × 1.1667
|
||||
$zeta: 18; // 18 = 18 × 1
|
||||
|
||||
|
||||
// $T y p e S c a l e U n i t
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
$type-scale-unit-value: rem;
|
||||
|
||||
|
||||
// $T e x t I n d e n t a t i o n
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
$indent-val: 1.5em;
|
||||
|
||||
|
||||
// $S t a t s T a b
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
$stats-font-size: 1.5rem;
|
||||
$stats-list-margin: 0 0.625rem 0 0;
|
||||
$stats-list-padding: 0 0.625rem 0 0;
|
||||
$stats-item-font-size: 0.875rem;
|
||||
$stats-item-margin: 0.125rem 0 0 0;
|
||||
$stats-border-style: 0.125rem solid #ccc;
|
||||
|
||||
|
||||
|
||||
// ==========================================================================
|
||||
//
|
||||
// $F o n t f a c e s
|
||||
//
|
||||
// ==========================================================================
|
||||
|
||||
|
||||
// $U N I C O D E - R A N G E A m p e r s a n d
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
@font-face {
|
||||
font-family: '#{$amp-fontface-name}';
|
||||
src: $amp-fontface-source;
|
||||
unicode-range: U+0026;
|
||||
}
|
||||
|
||||
// Ampersand fallback font for unicode range
|
||||
@font-face {
|
||||
font-family: '#{$amp-fontface-name}';
|
||||
src: $amp-fontface-fallback;
|
||||
unicode-range: U+270C;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ==========================================================================
|
||||
//
|
||||
// $F u n c t i o n s
|
||||
//
|
||||
// ==========================================================================
|
||||
|
||||
|
||||
// $C o n t e x t C a l c u l a t o r
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
@function ems($target, $context) {
|
||||
@return ($target/$context)#{em};
|
||||
}
|
||||
|
||||
|
||||
// $M o d u l a r S c a l e
|
||||
// --------------------------------------------------------------------------
|
||||
// http://thesassway.com/projects/modular-scale
|
||||
|
||||
@function modular-scale($scale, $base, $value) {
|
||||
// divide a given font-size by base font-size & return a relative em value
|
||||
@return ($scale/$base)#{$value};
|
||||
}
|
||||
|
||||
@function measure-margin($scale, $measure, $value) {
|
||||
// divide 1 unit of measure by given font-size & return a relative em value
|
||||
@return ($measure/$scale)#{$value};
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ==========================================================================
|
||||
//
|
||||
// $M i x i n s
|
||||
//
|
||||
// ==========================================================================
|
||||
|
||||
|
||||
// $M o d u l a r S c a l e
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
// $Typographic scale
|
||||
@mixin modular-scale($scale, $base, $value, $measure:"") {
|
||||
font-size: $scale#{px};
|
||||
font-size: modular-scale($scale, $base, $value);
|
||||
@if $measure != "" {
|
||||
margin-bottom: measure-margin($scale, $measure, $value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// $B o d y C o p y
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
@mixin base-type($weight, $line-height, $font-size, $font-family...) {
|
||||
@if $sans-serif-boolean {
|
||||
font: $weight #{$font-size}%/#{$line-height} $font-family;
|
||||
}@else {
|
||||
font: $weight #{$font-size}%/#{$line-height} $font-family-serif;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// $H y p h e n
|
||||
// --------------------------------------------------------------------------
|
||||
//http://trentwalton.com/2011/09/07/css-hyphenation
|
||||
|
||||
@mixin css-hyphens($val) {
|
||||
// Accepted values: [ none | manual | auto ]
|
||||
-webkit-hyphens: $val; // Safari 5.1 thru 6, iOS 4.2 thru 6
|
||||
-moz-hyphens: $val; // Firefox 16 thru 20
|
||||
-ms-hyphens: $val; // IE10
|
||||
hyphens: $val; // W3C standard
|
||||
};
|
||||
|
||||
|
||||
// $S m a l l c a p s
|
||||
// --------------------------------------------------------------------------
|
||||
// http://blog.hypsometry.com/articles/true-small-capitals-with-font-face
|
||||
// ISSUE#1 : https://github.com/zakkain/web-thang/issues/1
|
||||
|
||||
@mixin smallcaps($color, $font-weight) {
|
||||
// depends on the font family.
|
||||
// some font-families don't support small caps
|
||||
// or don't provide them with their web font.
|
||||
font-variant: small-caps;
|
||||
font-weight: $font-weight;
|
||||
text-transform: lowercase;
|
||||
color: $color;
|
||||
}
|
||||
|
||||
|
||||
// $F o n t - S i z e - A d j u s t
|
||||
// --------------------------------------------------------------------------
|
||||
// correct x-height for fallback fonts: requires secret formula
|
||||
// yet to be discovered. This is still wacky for support. Use
|
||||
// wisely grasshopper.
|
||||
|
||||
@mixin font-size-adjust($adjust-value) {
|
||||
// firefox 17+ only (as of Feb. 2013)
|
||||
font-size-adjust: $adjust-value;
|
||||
}
|
||||
|
||||
|
||||
// $A m p e r s a n d
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
@mixin ampersand($amp-font-family...) {
|
||||
font-family: $amp-font-family;
|
||||
}
|
||||
|
||||
%ampersand-placeholder {
|
||||
@include ampersand($amp-fontface-name, $amp-font-family);
|
||||
}
|
||||
|
||||
// Call your ampersand on any element you wish from another stylesheet
|
||||
// using this Sass extend we've provided...
|
||||
// @extend %ampersand-placeholder;
|
||||
|
||||
|
||||
|
||||
// $W o r d W r a p
|
||||
// --------------------------------------------------------------------------
|
||||
// Silent Sass Classes - A.K.A Placeholders
|
||||
//
|
||||
// normal: Indicates that lines may only break at normal word break points.
|
||||
// break-word : Indicates that normally unbreakable words may be broken at
|
||||
// arbitrary points if there are no otherwise acceptable break points in the line.
|
||||
|
||||
%breakword {
|
||||
word-wrap: breakword;
|
||||
}
|
||||
|
||||
%normal-wrap {
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
%inherit-wrap {
|
||||
word-wrap: auto;
|
||||
}
|
||||
|
||||
|
||||
// $D r o p c a p s
|
||||
// --------------------------------------------------------------------------
|
||||
/**
|
||||
* Dropcap Sass @include
|
||||
* Use the following Sass @include with any selector you feel necessary.
|
||||
*
|
||||
@include dropcap($float: left, $font-size: 4em, $font-family: inherit, $text-indent: 0, $margin: inherit, $padding: inherit, $color: inherit, $lineHeight: 1, $bg: transparent);
|
||||
*
|
||||
* Extend this object into your custom stylesheet.
|
||||
*
|
||||
*/
|
||||
|
||||
// Include your '@include dropcap()' mixin and pass the following
|
||||
// arguments below. Feel free to pass in arguments we've provided.
|
||||
// At this time you cannot pass in font-family arguments but you're gonna
|
||||
// change that anyway so why not just make that separately in your declaration.
|
||||
@mixin dropcap($float: left, $font-size: 4em, $font-family: inherit, $text-indent: 0, $margin: inherit, $padding: inherit, $color: inherit, $lineHeight: 1, $bg: transparent) {
|
||||
&:first-letter {
|
||||
float: $float;
|
||||
margin: $margin;
|
||||
padding: $padding;
|
||||
font-size: $font-size;
|
||||
font-family: $font-family;
|
||||
line-height: $lineHeight;
|
||||
text-indent: $text-indent;
|
||||
background: $bg;
|
||||
color: $color;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// $D e f i n i t i o n L i s t
|
||||
// --------------------------------------------------------------------------
|
||||
// lining
|
||||
// http://lea.verou.me/2012/02/flexible-multiline-definition-lists-with-2-lines-of-css
|
||||
//
|
||||
// dictionary-style
|
||||
// http://lea.verou.me/2012/02/flexible-multiline-definition-lists-with-2-lines-of-css
|
||||
|
||||
@mixin definition-list-style($style) {
|
||||
// lining style
|
||||
@if $style == lining {
|
||||
dt,
|
||||
dd {
|
||||
display: inline;
|
||||
margin: 0;
|
||||
}
|
||||
dt,
|
||||
dd {
|
||||
& + dt {
|
||||
&:before {
|
||||
content: "\A";
|
||||
white-space: pre;
|
||||
}
|
||||
}
|
||||
}
|
||||
dd {
|
||||
& + dd {
|
||||
&:before {
|
||||
content: ", ";
|
||||
}
|
||||
}
|
||||
&:before {
|
||||
content: ": ";
|
||||
margin-left: -0.2rem; //removes extra space between the dt and the colon
|
||||
}
|
||||
}
|
||||
}
|
||||
// dictionary-style
|
||||
@if $style == dictionary-style {
|
||||
dt {
|
||||
display: inline;
|
||||
counter-reset: definitions;
|
||||
& + dt {
|
||||
&:before {
|
||||
content: ", ";
|
||||
margin-left: -0.2rem; // removes extra space between the dt and the comma
|
||||
}
|
||||
}
|
||||
}
|
||||
dd {
|
||||
display: block;
|
||||
counter-increment: definitions;
|
||||
&:before {
|
||||
content: counter(definitions, decimal) ". ";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ==========================================================================
|
||||
//
|
||||
// $T y p e l a t e S t y l i n g
|
||||
//
|
||||
// ==========================================================================
|
||||
|
||||
|
||||
// $G l o b a l s
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
html {
|
||||
@include base-type($font-properties...);
|
||||
}
|
||||
|
||||
body {
|
||||
// Ala Trent Walton
|
||||
@include css-hyphens(auto);
|
||||
|
||||
// normal: Indicates that lines may only break at normal word break points.
|
||||
// break-word : Indicates that normally unbreakable words may be broken at ...
|
||||
// arbitrary points if there are no otherwise acceptable break points in the line.
|
||||
@extend %breakword;
|
||||
color: $body-copy-color;
|
||||
}
|
||||
|
||||
|
||||
// $H e a d i n g s
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
// styles for all headings, in the style of @csswizardry
|
||||
%hN {
|
||||
// voodoo to enable ligatures and kerning
|
||||
text-rendering: optimizeLegibility;
|
||||
// this fixes huge spaces when a heading wraps onto two lines
|
||||
line-height: 1;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
// make a multi-dimensional array, where:
|
||||
// the first value is the name of the class
|
||||
// and the second value is the variable for the size
|
||||
$sizes: tera $tera, giga $giga, mega $mega, alpha $alpha, beta $beta, gamma $gamma, delta $delta, epsilon $epsilon, zeta $zeta;
|
||||
|
||||
// for each size in the scale, create a class
|
||||
@each $size in $sizes {
|
||||
.#{nth($size, 1)} {
|
||||
@include modular-scale(nth($size, 2), $font-base, '#{$type-scale-unit-value}', $measure);
|
||||
}
|
||||
}
|
||||
|
||||
// associate h1-h6 tags with their appropriate greek heading
|
||||
h1 { @extend .alpha; @extend %hN; }
|
||||
h2 { @extend .beta; @extend %hN; }
|
||||
h3 { @extend .gamma; @extend %hN; }
|
||||
h4 { @extend .delta; @extend %hN; }
|
||||
h5 { @extend .epsilon; @extend %hN; }
|
||||
h6 { @extend .zeta; @extend %hN; }
|
||||
|
||||
|
||||
// $ P a r a g r a p h s
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
p {
|
||||
& + p {
|
||||
//siblings indentation
|
||||
text-indent: $indent-val;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// $C o d e b l o c k s
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
@mixin white-space($wrap-space) {
|
||||
@if $wrap-space == 'pre-wrap' {
|
||||
white-space: #{-moz-}$wrap-space; // Firefox 1.0-2.0
|
||||
white-space: $wrap-space; // current browsers
|
||||
} @else {
|
||||
white-space: $wrap-space;
|
||||
}
|
||||
}
|
||||
|
||||
pre code {
|
||||
@extend %normal-wrap;
|
||||
@include white-space(pre-wrap);
|
||||
}
|
||||
|
||||
pre {
|
||||
@include white-space(pre);
|
||||
}
|
||||
|
||||
code {
|
||||
@include white-space(pre);
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
|
||||
// $ S m a l l c a p s
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Abbreviations Markup
|
||||
*
|
||||
<abbr title="hyper text markup language">HMTL</abbr>
|
||||
*
|
||||
* Extend this object into your markup.
|
||||
*
|
||||
*/
|
||||
abbr {
|
||||
@include smallcaps(gray, 600);
|
||||
&:hover {
|
||||
cursor: help;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// $ H e a d i n g s C o l o r
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
color: $heading-color;
|
||||
}
|
||||
|
||||
|
||||
// $ D e f i n i t i o n L i s t s
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Lining Definition Style Markup
|
||||
*
|
||||
<dl class="lining">
|
||||
<dt><b></b></dt>
|
||||
<dd></dd>
|
||||
</dl>
|
||||
*
|
||||
* Extend this object into your markup.
|
||||
*
|
||||
*/
|
||||
.lining {
|
||||
@include definition-list-style(lining);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dictionary Definition Style Markup
|
||||
*
|
||||
<dl class="dictionary-style">
|
||||
<dt><b></b></dt>
|
||||
<dd></dd>
|
||||
</dl>
|
||||
*
|
||||
* Extend this object into your markup.
|
||||
*
|
||||
*/
|
||||
.dictionary-style {
|
||||
@include definition-list-style(dictionary-style);
|
||||
}
|
||||
|
||||
|
||||
// $S t a t s T a b
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Stats Tab Markup
|
||||
*
|
||||
<ul class="stats-tabs">
|
||||
<li><a href="#">[value]<b>[name]</b></a></li>
|
||||
</ul>
|
||||
*
|
||||
* Extend this object into your markup.
|
||||
*
|
||||
*/
|
||||
.stats-tabs {
|
||||
padding: 0;
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: $stats-list-margin;
|
||||
padding: $stats-list-padding;
|
||||
border-right: $stats-border-style;
|
||||
&:last-child {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
}
|
||||
a {
|
||||
display: inline-block;
|
||||
font-size: $stats-font-size;
|
||||
font-weight: bold;
|
||||
b {
|
||||
display: block;
|
||||
margin: $stats-item-margin;
|
||||
font-size: $stats-item-font-size;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// $Blockquote Cites
|
||||
// --------------------------------------------------------------------------
|
||||
/**
|
||||
* Blockquote Markup
|
||||
*
|
||||
<blockquote cite="">
|
||||
<p>″″</p>
|
||||
<cite>
|
||||
<small><a href=""></a></small>
|
||||
</cite>
|
||||
</blockquote>
|
||||
*
|
||||
* Extend this object into your markup.
|
||||
*
|
||||
*/
|
||||
|
||||
@mixin cite-style($display:block, $text-align:right, $font-size: .875em) {
|
||||
display: $display;
|
||||
font-size: $font-size;
|
||||
text-align: $text-align;
|
||||
}
|
||||
|
||||
%cite {
|
||||
@include cite-style;
|
||||
}
|
||||
|
||||
|
||||
// $Pull Quotes
|
||||
// --------------------------------------------------------------------------
|
||||
// http://24ways.org/2005/swooshy-curly-quotes-without-images
|
||||
//
|
||||
// http://todomvc.com - Thanks sindresorhus!
|
||||
// https://github.com/typeplate/typeplate.github.com/issues/49
|
||||
|
||||
/**
|
||||
* Pull Quotes Markup
|
||||
*
|
||||
<aside class="pull-quote">
|
||||
<blockquote>
|
||||
<p></p>
|
||||
</blockquote>
|
||||
</aside>
|
||||
*
|
||||
* Extend this object into your custom stylesheet.
|
||||
*
|
||||
*/
|
||||
|
||||
@mixin pull-quotes($font-size, $opacity) {
|
||||
position: relative;
|
||||
padding: ems($font-size, $font-size);
|
||||
&:before,
|
||||
&:after {
|
||||
height: ems($font-size, $font-size);
|
||||
opacity: $opacity;
|
||||
position: absolute;
|
||||
font-size: $font-size;
|
||||
}
|
||||
&:before {
|
||||
content: '“';
|
||||
top: 0em;
|
||||
left: 0em;
|
||||
}
|
||||
&:after {
|
||||
content: '”';
|
||||
bottom: 0em;
|
||||
right: 0em;
|
||||
}
|
||||
}
|
||||
|
||||
.pull-quote {
|
||||
@include pull-quotes(4em, .15);
|
||||
}
|
||||
|
||||
|
||||
// $Figures
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Figures Markup
|
||||
*
|
||||
<figure>
|
||||
<figcaption>
|
||||
<strong>Fig. 4.2 | </strong>Type Anatomy, an excerpt from Mark Boulton's book<cite title="http://designingfortheweb.co.uk/book/part3/part3_chapter11.php">"Designing for the Web"</cite>
|
||||
</figcaption>
|
||||
</figure>
|
||||
*
|
||||
* Extend this object into your markup.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// $Footnotes
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Footnote Markup : Replace 'X' with your unique number for each footnote
|
||||
*
|
||||
<article>
|
||||
<p><sup><a href="#fn-itemX" id="fn-returnX"></a></sup></p>
|
||||
<footer>
|
||||
<ol class="foot-notes">
|
||||
<li id="fn-itemX"><a href="#fn-returnX">↩</a></li>
|
||||
</ol>
|
||||
</footer>
|
||||
</article>
|
||||
*
|
||||
* Extend this object into your markup.
|
||||
*
|
||||
*/
|
53
core/admin/assets/sass/screen.scss
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Welcome to Ghost - all styles for the Ghost platform are located within
|
||||
* this set of Sass files. Use this file like a table of contents.
|
||||
*/
|
||||
|
||||
/* ==========================================================================
|
||||
Modules - These styles are re-used in many areas, and are grouped by type.
|
||||
========================================================================== */
|
||||
|
||||
@import "modules/mixins";
|
||||
/* Sass variables like colours, font sizes, basic styles. */
|
||||
|
||||
@import "modules/normalize";
|
||||
/* Browser cross compatibility normalisation*/
|
||||
|
||||
@import "modules/typeplate";
|
||||
/* All the styles controlling the typographic styles. */
|
||||
|
||||
@import "modules/grid";
|
||||
/* The responsive grid structure used to control the main layout. */
|
||||
|
||||
@import "modules/icons";
|
||||
/* All the styles controlling icons. */
|
||||
|
||||
@import "modules/animations";
|
||||
/* Keyframe animations. */
|
||||
|
||||
@import "modules/global";
|
||||
/* Global elements for the UI, like the header and footer. */
|
||||
|
||||
@import "modules/forms";
|
||||
/* All the styles controlling forms and form fields. */
|
||||
|
||||
|
||||
|
||||
/* ==========================================================================
|
||||
Layouts - Styles for specific admin screen layouts, grouped by screen.
|
||||
========================================================================== */
|
||||
|
||||
@import "layouts/dashboard";
|
||||
/* The default admin page, the dashboard. */
|
||||
|
||||
@import "layouts/manage";
|
||||
/* The manage posts screen. */
|
||||
|
||||
@import "layouts/editor";
|
||||
/* The write/edit post screen. */
|
||||
|
||||
@import "layouts/settings";
|
||||
/* The settings screen. */
|
||||
|
||||
@import "layouts/login";
|
||||
/* The settings screen. */
|
167
core/admin/controllers/index.js
Normal file
@ -0,0 +1,167 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var Ghost = require('../../ghost'),
|
||||
_ = require('underscore'),
|
||||
fs = require('fs'),
|
||||
Showdown = require('showdown'),
|
||||
converter = new Showdown.converter(),
|
||||
|
||||
ghost = new Ghost(),
|
||||
adminNavbar,
|
||||
adminControllers;
|
||||
|
||||
// TODO: combine path/navClass to single "slug(?)" variable with no prefix
|
||||
adminNavbar = {
|
||||
dashboard: {
|
||||
name: 'Dashboard',
|
||||
navClass: 'dashboard',
|
||||
key: 'admin.navbar.dashboard',
|
||||
defaultString: 'dashboard',
|
||||
path: ''
|
||||
},
|
||||
blog: {
|
||||
name: 'Content',
|
||||
navClass: 'content',
|
||||
key: 'admin.navbar.blog',
|
||||
defaultString: 'blog',
|
||||
path: '/blog'
|
||||
},
|
||||
add: {
|
||||
name: 'New Post',
|
||||
navClass: 'editor',
|
||||
key: 'admin.navbar.editor',
|
||||
defaultString: 'editor',
|
||||
path: '/editor'
|
||||
},
|
||||
settings: {
|
||||
name: 'Settings',
|
||||
navClass: 'settings',
|
||||
key: 'admin.navbar.settings',
|
||||
defaultString: 'settings',
|
||||
path: '/settings'
|
||||
}
|
||||
};
|
||||
|
||||
// TODO - make this a util or helper
|
||||
function setSelected(list, name) {
|
||||
_.each(list, function (item, key) {
|
||||
item.selected = key === name;
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
adminControllers = {
|
||||
'index': function (req, res) {
|
||||
res.render('dashboard', {
|
||||
bodyClass: 'dashboard',
|
||||
adminNav: setSelected(adminNavbar, 'dashboard')
|
||||
});
|
||||
},
|
||||
'editor': function (req, res) {
|
||||
if (req.params.id !== undefined) {
|
||||
ghost.dataProvider().posts.findOne({'id': parseInt(req.params.id, 10)}, function (error, post) {
|
||||
res.render('editor', {
|
||||
bodyClass: 'editor',
|
||||
adminNav: setSelected(adminNavbar, 'blog'),
|
||||
title: post.title,
|
||||
content: post.content
|
||||
});
|
||||
});
|
||||
} else {
|
||||
res.render('editor', {
|
||||
bodyClass: 'editor',
|
||||
adminNav: setSelected(adminNavbar, 'add')
|
||||
});
|
||||
}
|
||||
},
|
||||
'blog': function (req, res) {
|
||||
ghost.dataProvider().posts.findAll(function (error, posts) {
|
||||
res.render('blog', {
|
||||
bodyClass: 'manage',
|
||||
adminNav: setSelected(adminNavbar, 'blog'),
|
||||
posts: posts
|
||||
});
|
||||
});
|
||||
},
|
||||
'settings': function (req, res) {
|
||||
res.render('settings', {
|
||||
bodyClass: 'settings',
|
||||
adminNav: setSelected(adminNavbar, 'settings')
|
||||
});
|
||||
},
|
||||
'debug': { /* ugly temporary stuff for managing the app before it's properly finished */
|
||||
index: function (req, res) {
|
||||
res.render('debug', {
|
||||
bodyClass: 'settings',
|
||||
adminNav: setSelected(adminNavbar, 'settings'),
|
||||
messages: req.flash(),
|
||||
test: 'Hello world'
|
||||
});
|
||||
},
|
||||
'dbdelete': function (req, res) {
|
||||
fs.writeFile(__dirname + '/../ghost/data/datastore.db', '', function (error) {
|
||||
if (error) {
|
||||
req.flash('error', error);
|
||||
} else {
|
||||
req.flash('success', 'Everything got deleted');
|
||||
}
|
||||
res.redirect('/ghost/debug');
|
||||
});
|
||||
},
|
||||
'dbpopulate': function (req, res) {
|
||||
ghost.dataProvider().populateData(function (error) {
|
||||
if (error) {
|
||||
req.flash('error', error);
|
||||
} else {
|
||||
req.flash('success', 'Data populated');
|
||||
}
|
||||
res.redirect('/ghost/debug');
|
||||
});
|
||||
}
|
||||
},
|
||||
'posts': {
|
||||
'index': function (req, res) {
|
||||
|
||||
},
|
||||
'create': function (req, res) {
|
||||
var entry = {
|
||||
title: req.body.title,
|
||||
content: req.body.markdown,
|
||||
contentHtml: '',
|
||||
language: ghost.config().defaultLang,
|
||||
status: ghost.statuses().draft,
|
||||
featured: false
|
||||
};
|
||||
|
||||
entry.contentHtml = converter.makeHtml(entry.content);
|
||||
|
||||
ghost.dataProvider().posts.add(entry, function (error, post) {
|
||||
if (!error) {
|
||||
console.log('added', post);
|
||||
res.json({id: post.id});
|
||||
} else {
|
||||
res.json(400, {error: post.errors});
|
||||
}
|
||||
});
|
||||
},
|
||||
'edit': function (req, res) {
|
||||
var entry = {
|
||||
id: parseInt(req.body.id, 10),
|
||||
title: req.body.title,
|
||||
content: req.body.markdown,
|
||||
contentHtml: ''
|
||||
};
|
||||
|
||||
entry.contentHtml = converter.makeHtml(entry.content);
|
||||
|
||||
ghost.dataProvider().posts.edit(entry, function (error, post) {
|
||||
console.log('edited', post);
|
||||
res.json({id: parseInt(post.id, 10)});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = adminControllers;
|
||||
}());
|
61
core/admin/views/blog.hbs
Normal file
@ -0,0 +1,61 @@
|
||||
{{!< default}}
|
||||
<main role="main">
|
||||
|
||||
<section class="content-list">
|
||||
<header class="floatingheader">
|
||||
<section class="content-filter">
|
||||
<a class="dropdown" href="#" data-toggle=".menu-drop">All Posts</a>
|
||||
<ul class="menu-drop">
|
||||
<li class="active"><a href="#">All Posts</a></li>
|
||||
<li><a href="#">Recently Edited</a></li>
|
||||
<li><a href="#">By Author...</a></li>
|
||||
<li><a href="#">Search</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
<a href="/ghost/editor" class="button button-add"><span class="hidden">New Post</span></a>
|
||||
</header>
|
||||
<section class="content-list-content">
|
||||
<ol>
|
||||
{{#each posts}}
|
||||
{{! #if featured class="featured"{{/if}}
|
||||
<li data-id="{{id}}" data-content="{{contentHtml}}">
|
||||
<a class="permalink" href="#">
|
||||
<h3 class="entry-title">{{title}}</h3>
|
||||
<section class="entry-meta">
|
||||
<time datetime="2013-01-04" class="date">5 minutes ago</time>
|
||||
{{!<span class="views">1,934</span>}}
|
||||
</section>
|
||||
</a>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ol>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section class="content-preview">
|
||||
<header class="floatingheader">
|
||||
|
||||
<a class="unfeatured" href="#"><span class="hidden">Star</span></a>
|
||||
{{! TODO: JavaScript toggle featured/unfeatured}}
|
||||
|
||||
<span class="status">Published</span>
|
||||
<span class="normal">by</span>
|
||||
<span class="author">John O'Nolan</span>
|
||||
<section class="post-controls">
|
||||
<a class="post-edit" href="#"><span class="hidden">Edit Post</span></a>
|
||||
<a class="post-settings" href="#" data-toggle=".menu-drop-right"><span class="hidden">Post Settings</span></a>
|
||||
<ul class="menu-drop-right">
|
||||
<li><a href="#">URL</a></li>
|
||||
<li><a href="#">Something</a></li>
|
||||
<li><a href="#">Delete</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
</header>
|
||||
<section class="content-preview-content">
|
||||
<div class="wrapper"></div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<script src="/core/admin/assets/js/blog.js"></script>
|
254
core/admin/views/dashboard.hbs
Normal file
@ -0,0 +1,254 @@
|
||||
{{!< default}}
|
||||
<main role="main">
|
||||
|
||||
<div class="time widget"></div>
|
||||
<div class="image widget"></div>
|
||||
<div class="posts widget none">
|
||||
<div class="chart">
|
||||
<canvas id="poststats" width="250" height="250"></canvas>
|
||||
<ul class="data">
|
||||
<li><span class="ready">9</span> Ready</li>
|
||||
<li><span class="pending">4</span> Pending</li>
|
||||
<li><span class="draft">1</span> Draft</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stats widget"></div>
|
||||
<div class="facebook widget"></div>
|
||||
<div class="gplus widget none"></div>
|
||||
<div class="twitter widget"></div>
|
||||
<div class="campaignmonitor widget none"></div>
|
||||
|
||||
{{!
|
||||
<section class="dashboard-controls">
|
||||
<div class="text left"><strong>Welcome back</strong>, John.</div>
|
||||
<nav class="controls-nav">
|
||||
<ul class="nav inline">
|
||||
<li><a href="/ghost/editor"><span class="icon-new"></span> New Post</a></li>
|
||||
<li><a href="#"><span class="icon-users"></span> Authors</a></li>
|
||||
<li><a href="#"><span class="icon-analytics"></span> Analytics</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="text right"><a href="#"><span class="icon-settings"></span><span class="hidden">Settings</span></a></div>
|
||||
<div class="clearfix"></div><!--TODO: replace this later with something less shit-->
|
||||
</section>
|
||||
|
||||
<section class="widget time-date">
|
||||
<header>
|
||||
London, United Kingdom
|
||||
</header>
|
||||
<section class="content">
|
||||
<div class="time">
|
||||
8:55<span>am</span>
|
||||
</div>
|
||||
<div class="date"><!--TODO: convert to html5 <date>-->
|
||||
<span>Wednesday</span>
|
||||
13 June 2012
|
||||
</div>
|
||||
</section>
|
||||
<footer>
|
||||
Timezone: UTC +1
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
<section class="widget">
|
||||
<header>
|
||||
Top Authors This Month
|
||||
</header>
|
||||
<section class="content">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>Posts</td>
|
||||
<td>Comments</td>
|
||||
<td>tweets</td>
|
||||
<td>Likes</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><strong class="text-uppercase"><img class="user-img" src="/ghost/assets/img/user.jpg" width="34px" height="34px" alt=""> John</strong></td>
|
||||
<td><strong class="callout">32</strong> <span>Posts</span></td>
|
||||
<td><strong>231</strong> <span>Comments</span></td>
|
||||
<td><strong>103</strong> <span>tweets</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong class="text-uppercase"><img class="user-img" src="/ghost/assets/img/user.jpg" width="34px" height="34px" alt=""> James</strong></td>
|
||||
<td><strong>32</strong> <span>Posts</span></td>
|
||||
<td><strong class="callout">231</strong> <span>Comments</span></td>
|
||||
<td><strong>103</strong> <span>tweets</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong class="text-uppercase"><img class="user-img" src="/ghost/assets/img/user.jpg" width="34px" height="34px" alt=""> Jerry</strong></td>
|
||||
<td><strong>32</strong> <span>Posts</span></td>
|
||||
<td><strong>231</strong> <span>Comments</span></td>
|
||||
<td><strong class="callout">103</strong> <span>tweets</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<footer>
|
||||
Ghost Stats
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
<section class="widget post-statuses">
|
||||
<header>
|
||||
Post Statuses
|
||||
</header>
|
||||
<section class="content">
|
||||
<div class="status-levels left">
|
||||
<div class="scheduled" style="height: 30px;">Scheduled</div>
|
||||
<div class="pending" style="height: 50px;">Pending</div>
|
||||
<div class="draft" style="height: 60px;">Draft</div>
|
||||
</div>
|
||||
<div class="status-text left">
|
||||
<div class="scheduled"><strong>5</strong> Scheduled</div>
|
||||
<div class="pending"><strong>12</strong> Pending</div>
|
||||
<div class="draft"><strong>32</strong> Draft</div>
|
||||
</div>
|
||||
</section>
|
||||
<footer>
|
||||
Ghost Stats
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
<section class="widget total-views">
|
||||
<header>
|
||||
Total Page Views (Last 30 Days)
|
||||
</header>
|
||||
<section class="content">
|
||||
<div class="widget-stats">
|
||||
<span>37,921</span>
|
||||
<span>
|
||||
Previous <strong>32,419</strong> / <strong class="positive-text">+15.4%</strong>
|
||||
</span>
|
||||
</div>
|
||||
</section>
|
||||
<footer>
|
||||
Google Analytics
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
<section class="widget live-visitors">
|
||||
<header>
|
||||
Live Visitors
|
||||
</header>
|
||||
<section class="content">
|
||||
<div class="widget-stats">
|
||||
<span>124</span>
|
||||
<span>
|
||||
<strong>391</strong> max this month
|
||||
</span>
|
||||
</div>
|
||||
</section>
|
||||
<footer>
|
||||
Woopra
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
<section class="widget">
|
||||
<header>
|
||||
Twitter Followers
|
||||
</header>
|
||||
<section class="content">
|
||||
<div class="widget-stats">
|
||||
<span>12,304</span>
|
||||
<span>
|
||||
<strong class="positive-text">+123</strong> this month
|
||||
</span>
|
||||
</div>
|
||||
</section>
|
||||
<footer>
|
||||
@ghost
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
<section class="widget todays-traffic">
|
||||
<header>
|
||||
Today’s Traffic (Actions)
|
||||
</header>
|
||||
<section class="content">
|
||||
<ul class="nav">
|
||||
<li>
|
||||
<div>Post Title Excerpt Which is Li... <strong class="right">327</strong></div>
|
||||
</li>
|
||||
<li>
|
||||
<div>My homepage <strong class="right">327</strong></div>
|
||||
</li>
|
||||
<li>
|
||||
<div>Another long ass post about som... <strong class="right">327</strong></div>
|
||||
</li>
|
||||
<li>
|
||||
<div>Boracay time! <strong class="right">327</strong></div>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
<footer>
|
||||
Woopra
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
<section class="widget">
|
||||
<header>
|
||||
Total Likes
|
||||
</header>
|
||||
<section class="content">
|
||||
<div class="widget-stats">
|
||||
<span>6,931</span>
|
||||
<span>
|
||||
<strong class="negative-text">-23</strong> this month
|
||||
</span>
|
||||
</div>
|
||||
</section>
|
||||
<footer>
|
||||
Facebook
|
||||
</footer>
|
||||
</section>
|
||||
}}
|
||||
|
||||
</main>
|
||||
|
||||
<script src="/core/admin/assets/lib/chart.min.js"></script>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
|
||||
//$('body').click(function(){
|
||||
$('.time').fadeIn(1000);
|
||||
$('.image').delay(300).fadeIn(1000);
|
||||
$('.posts').delay(600).fadeIn(900, function(){
|
||||
|
||||
var ctx = $("#poststats").get(0).getContext("2d");
|
||||
var data = [
|
||||
{
|
||||
value: 9,
|
||||
color:"#9ec14a"
|
||||
},
|
||||
{
|
||||
value : 4,
|
||||
color : "#f9e15d"
|
||||
},
|
||||
{
|
||||
value : 2,
|
||||
color : "#EB5700"
|
||||
}
|
||||
]
|
||||
var options = {
|
||||
animationEasing: 'easeOutQuart',
|
||||
percentageInnerCutout: 60,
|
||||
segmentStrokeColor : "#efefef"
|
||||
}
|
||||
var poststats = new Chart(ctx).Doughnut(data, options);
|
||||
|
||||
});
|
||||
|
||||
$('.stats').delay(800).fadeIn(1000);
|
||||
$('.facebook').delay(1000).fadeIn(1000);
|
||||
$('.gplus').delay(1200).fadeIn(1000);
|
||||
$('.twitter').delay(1300).fadeIn(1000);
|
||||
$('.campaignmonitor').delay(1400).fadeIn(1000);
|
||||
//});
|
||||
|
||||
});
|
||||
</script>
|
41
core/admin/views/debug.hbs
Normal file
@ -0,0 +1,41 @@
|
||||
{{!< default}}
|
||||
<main role="main">
|
||||
|
||||
<div class="wrapper">
|
||||
<aside class="settings-sidebar" role="complementary">
|
||||
<header>
|
||||
<h1 class="title">Ugly Debug Tools</h1>
|
||||
</header>
|
||||
<nav class="settings-menu">
|
||||
<ul>
|
||||
<li class="Data management"><a href="#">General</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</aside>
|
||||
<section class="settings-content">
|
||||
<header>
|
||||
<h2 class="title">General</h2>
|
||||
<button class="button-save">Save</button>
|
||||
</header>
|
||||
<section class="content">
|
||||
{{> flashes}}
|
||||
<form id="settings-general">
|
||||
<fieldset>
|
||||
<label>
|
||||
<b>Delete Database</b>
|
||||
<a href="/ghost/debug/db/delete/" class="button-delete">Delete</a>
|
||||
<p>Delete the entire database so you can start again with empty tables</p>
|
||||
</label>
|
||||
<label>
|
||||
<b>Populate Database</b>
|
||||
<a href="/ghost/debug/db/populate/" class="button-add">Populate</a>
|
||||
<p>Populate the database with the default fixtures (<strong>Warning: </strong>only works on empty DB)</p>
|
||||
</label>
|
||||
</fieldset>
|
||||
|
||||
</form>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
</main>
|
37
core/admin/views/default.hbs
Normal file
@ -0,0 +1,37 @@
|
||||
<!doctype html>
|
||||
<!--[if lt IE 7]><html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
|
||||
<!--[if (IE 7)&!(IEMobile)]><html class="no-js lt-ie9 lt-ie8" lang="en"><![endif]-->
|
||||
<!--[if (IE 8)&!(IEMobile)]><html class="no-js lt-ie9" lang="en"><![endif]-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Ghost</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<meta name="HandheldFriendly" content="True">
|
||||
<meta name="MobileOptimized" content="320">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
|
||||
<!-- For all browsers -->
|
||||
<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Lato:300,400,700">
|
||||
<link rel="stylesheet" href="/core/admin/assets/css/screen.css">
|
||||
|
||||
<link rel="shortcut icon" href="/favicon.ico">
|
||||
<link rel="logo" type="image/svg" href="/core/admin/assets/images/logo.svg"/>
|
||||
<meta http-equiv="cleartype" content="on">
|
||||
|
||||
<!-- need per file scripts and styles :/ -->
|
||||
<link rel="stylesheet" type="text/css" href="/core/admin/assets/lib/codemirror/codemirror.css"> <!-- TODO: Kill this - #29 -->
|
||||
|
||||
<!-- jQuery is for all so here for now -->
|
||||
<script type="text/javascript" src="/core/admin/assets/lib/jquery/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="/core/admin/assets/js/toggle.js"></script>
|
||||
<script type="text/javascript" src="/core/admin/assets/js/admin-ui-temp.js"></script>
|
||||
</head>
|
||||
<body class="{{bodyClass}}">
|
||||
{{> navbar}}
|
||||
{{{body}}}
|
||||
</body>
|
||||
</html>
|
65
core/admin/views/editor.hbs
Normal file
@ -0,0 +1,65 @@
|
||||
{{!< default}}
|
||||
<main role="main">
|
||||
{{! TODO: Add "scrolling" class only when one of the panels is scrolled down by 5px or more }}
|
||||
|
||||
<header>
|
||||
<section class="box entry-title">
|
||||
<input type="text" id="entry-title" placeholder="{{e "editor.entry_title.placeholder" "The Post Title Gets Inserted Up Here"}}" value="{{title}}">
|
||||
</section>
|
||||
</header>
|
||||
|
||||
<section class="entry-markdown active">
|
||||
<header class="floatingheader">
|
||||
{{e "editor.headers.markdown.label" "Markdown"}}
|
||||
<a class="markdown-help" href="#"><span class="hidden">What is Markdown?</span></a>
|
||||
</header>
|
||||
<section class="entry-markdown-content">
|
||||
<textarea id="entry-markdown">{{content}}</textarea>
|
||||
</section>
|
||||
</section>{{!.entry-markdown}}
|
||||
|
||||
<section class="entry-preview">
|
||||
<header class="floatingheader">
|
||||
Preview <span class="entry-word-count">0 words</span>
|
||||
</header>
|
||||
<section class="entry-preview-content">
|
||||
<div class="rendered-markdown">
|
||||
{{!The content gets inserted in here, bitches!}}
|
||||
</div>
|
||||
</section>
|
||||
</section>{{!.entry-preview}}
|
||||
|
||||
<footer id="publish-bar">
|
||||
<nav>
|
||||
<section id="entry-categories" href="#" class="left">
|
||||
<label class="category-label" for="categories"><span class="hidden">Categories</span></label>
|
||||
<div class="categories"></div>
|
||||
<input type="hidden" class="category-holder" id="category-holder">
|
||||
<input class="category-input" id="categories" type="text" data-populate-hidden="#category-holder" data-input-behaviour="tag" data-populate=".categories" />
|
||||
<ul class="suggestions overlay" data-populate=".categories"></ul>
|
||||
</section>
|
||||
<div class="right">
|
||||
<button id="entry-settings" href="#" class="button-link"><span class="hidden">Settings</span></button>
|
||||
<section id="entry-actions" class="splitbutton-save">
|
||||
<button type="button" class="button-save" data-state="save-draft">Save Draft</button>
|
||||
<a class="options up" href="#"><span class="hidden">Options</span></a>
|
||||
<ul class="editor-options overlay" style="display:none">
|
||||
<li data-title="publish-now" data-url=""><a href="#">Publish Now</a></li>
|
||||
<li data-title="queue" data-url=""><a href="#">Add to Queue</a></li>
|
||||
<li data-title="publish-on" data-url=""><a href="#">Publish on...</a></li>
|
||||
<li data-title="save-draft" data-url="" class="active"><a href="#">Save Draft</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
</nav>
|
||||
</footer>
|
||||
|
||||
</main>
|
||||
|
||||
<script src="/core/admin/assets/lib/codemirror/codemirror.js"></script>
|
||||
<script src="/core/admin/assets/lib/codemirror/mode/markdown/markdown.js"></script>
|
||||
<script src="/core/admin/assets/lib/showdown/showdown.js"></script>
|
||||
<script src="/core/admin/assets/lib/showdown/extensions/ghostdown.js"></script>
|
||||
<script src="/core/admin/assets/lib/shortcuts.js"></script>
|
||||
<script src="/core/admin/assets/js/editor.js"></script>
|
||||
<script src="/core/admin/assets/js/tagui.js"></script>
|
27
core/admin/views/partials/flashes.hbs
Normal file
@ -0,0 +1,27 @@
|
||||
<div id="flashed"></div>
|
||||
{{#if messages}}
|
||||
{{#each messages.error}}
|
||||
<section class="notification-error">
|
||||
{{.}}
|
||||
<a class="close" href="#"><span class="hidden">Close</span></a>
|
||||
</section>
|
||||
{{/each}}
|
||||
{{#each messages.success}}
|
||||
<section class="notification-success">
|
||||
{{.}}
|
||||
<a class="close" href="#"><span class="hidden">Close</span></a>
|
||||
</section>
|
||||
{{/each}}
|
||||
{{#each messages.warn}}
|
||||
<section class="notification-alert">
|
||||
{{.}}
|
||||
<a class="close" href="#"><span class="hidden">Close</span></a>
|
||||
</section>
|
||||
{{/each}}
|
||||
{{#each messages.info}}
|
||||
<section class="notification">
|
||||
{{.}}
|
||||
<a class="close" href="#"><span class="hidden">Close</span></a>
|
||||
</section>
|
||||
{{/each}}
|
||||
{{/if}}
|
25
core/admin/views/partials/navbar.hbs
Normal file
@ -0,0 +1,25 @@
|
||||
<header id="global-header" class="navbar">
|
||||
<a id="ghost" href="#" data-off-canvas="left"><span class="hidden">Ghost</span></a>
|
||||
<nav id="global-nav" role="navigation">
|
||||
<ul id="main-menu" >
|
||||
{{#each adminNav}}
|
||||
<li class="{{navClass}}{{#if selected}} active{{/if}}"><a href="/ghost{{path}}">{{name}}</a></li>
|
||||
{{/each}}
|
||||
|
||||
<li id="usermenu" class="subnav">
|
||||
<a href="#" data-toggle="ul">
|
||||
<img class="avatar" src="/core/admin/assets/img/user.jpg" alt="Avatar" />
|
||||
<span class="name">John O'Nolan</span>
|
||||
</a>
|
||||
<ul>
|
||||
<li class="usermenu-profile"><a href="#">Your Profile</a></li>
|
||||
<li class="divider"></li>
|
||||
<li class="usermenu-help"><a href="#">Help / Support</a></li>
|
||||
<li class="usermenu-shortcuts"><a href="#">Keyboard Shortcuts</a></li>
|
||||
<li class="divider"></li>
|
||||
<li class="usermenu-signout"><a href="#">Sign Out</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
171
core/admin/views/settings.hbs
Normal file
@ -0,0 +1,171 @@
|
||||
{{!< default}}
|
||||
<main role="main">
|
||||
|
||||
<div class="wrapper">
|
||||
<aside class="settings-sidebar" role="complementary">
|
||||
<header>
|
||||
<h1 class="title">Settings</h1>
|
||||
</header>
|
||||
<nav class="settings-menu">
|
||||
<ul>
|
||||
<li class="general active"><a href="#general">General</a></li>
|
||||
<li class="publishing"><a href="#content">Content</a></li>
|
||||
<li class="users"><a href="#users">Users</a></li>
|
||||
<li class="appearance"><a href="#">Appearance</a></li>
|
||||
<li class="services"><a href="#">Connected Services</a></li>
|
||||
<li class="plugins"><a href="#">Plugins</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</aside>
|
||||
<section id="general" class="settings-content active">
|
||||
<header>
|
||||
<h2 class="title">General</h2>
|
||||
<section class="page-actions">
|
||||
<button class="button-save">Save</button>
|
||||
</section>
|
||||
</header>
|
||||
<section class="content">
|
||||
<form id="settings-general">
|
||||
<fieldset>
|
||||
<label>
|
||||
<b>Blog Title</b>
|
||||
<input id="blog-title" type="text" value="John O'Nolan" />
|
||||
<p>How your blog name appears on the site</p>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<b>Blog Logo</b>
|
||||
<img src="/core/admin/assets/img/logo.png" alt="logo" height"38" width="381"/>
|
||||
<p>Display a logo on your site in place of blog title</p>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<b>Blog Icon</b>
|
||||
<img src="/core/admin/assets/img/test-icon.png" alt="logo" height"38" width="38"/>
|
||||
<p>The icon for your blog, used in your browser tab and elsewhere</p>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<b>Email Address</b>
|
||||
<input id="email-address" type="text" value="john@tryghost.org" />
|
||||
<p>Address to use for <a href="#">admin notifications</a></p>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" value="1" /> Show my email address on my public profile
|
||||
</label>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<b>URL Structure</b>
|
||||
<select id="url-structure" name="general[urlstructure]">
|
||||
<option value="post-name">Simple Post Name</option>
|
||||
<option value="date-based">Date Based</option>
|
||||
<option value="number based">Number Based</option>
|
||||
<option value="custom">Custom...</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
</fieldset>
|
||||
|
||||
<hr />
|
||||
|
||||
<fieldset>
|
||||
|
||||
<label>
|
||||
<b>Time Zone</b>
|
||||
<select id="url-structure" name="general[timezone]">
|
||||
<option value="1">Vienna (UTC+1)</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
</fieldset>
|
||||
|
||||
|
||||
</form>
|
||||
</section>
|
||||
</section>
|
||||
<section id="content" class="settings-content">
|
||||
<header>
|
||||
<h2 class="title">Content</h2>
|
||||
<section class="page-actions">
|
||||
<button class="button-save">Save</button>
|
||||
</section>
|
||||
</header>
|
||||
<section class="content">
|
||||
<form id="settings-general">
|
||||
<fieldset>
|
||||
<label>
|
||||
<b>Typography</b>
|
||||
<select id="url-structure" name="general[urlstructure]">
|
||||
<option value="post-name">Lato (Light)</option>
|
||||
</select>
|
||||
<p>Sexy sans-serif font that will make your toes tickle.</p>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" value="1" /> Load fonts directly from Google
|
||||
</label>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<b>Post Options</b>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" value="1" /> Display Post Meta
|
||||
<p>Post Author / Date / Views</p>
|
||||
</label>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" value="1" /> Show Author Box After Post
|
||||
</label>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" value="1" /> Enable Comments
|
||||
</label>
|
||||
</label>
|
||||
|
||||
</fieldset>
|
||||
|
||||
<hr />
|
||||
|
||||
<fieldset>
|
||||
|
||||
<label>
|
||||
<b>SEO Title Pattern</b>
|
||||
<input id="blog-title" type="text" value="[Post Name] - [Site Title]" />
|
||||
<p>The pattern used to display your title tags</p>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<b>SEO Description Pattern</b>
|
||||
<input id="blog-title" type="text" value="Auto" />
|
||||
<p>The pattern used to display your meta descriptions</p>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<b>Google+</b>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" value="1" /> Connect to author profile on Google
|
||||
</label>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<b>Home Page Description</b>
|
||||
<textarea></textarea>
|
||||
<p>Display a logo on your site in place of blog title</p>
|
||||
</label>
|
||||
|
||||
</fieldset>
|
||||
|
||||
</form>
|
||||
</section>
|
||||
</section>
|
||||
<section id="users" class="settings-content">
|
||||
<header>
|
||||
<h2 class="title">Users</h2>
|
||||
<section class="page-actions">
|
||||
<button class="button-add">Add User</button>
|
||||
</section>
|
||||
</header>
|
||||
<section class="content">
|
||||
<img src="/core/admin/assets/img/users.png" alt="users" style="width:900px;height:auto" />
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
<script src="/core/admin/assets/js/settings.js"></script>
|
51
core/frontend/controllers/index.js
Normal file
@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Main controller for Ghost frontend
|
||||
*/
|
||||
|
||||
/*global require, module */
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var Ghost = require('../../ghost'),
|
||||
_ = require('underscore'),
|
||||
|
||||
ghost = new Ghost(),
|
||||
frontendControllers;
|
||||
|
||||
frontendControllers = {
|
||||
'homepage': function (req, res) {
|
||||
var featureCount = 0,
|
||||
postCount = 0,
|
||||
data;
|
||||
|
||||
ghost.dataProvider().posts.findAll(function (error, posts) {
|
||||
data = _.groupBy(posts, function (post) {
|
||||
var group = null;
|
||||
if (post.featured === true && featureCount < ghost.config().homepage.features) {
|
||||
featureCount += 1;
|
||||
group = 'features';
|
||||
} else if (postCount < ghost.config().homepage.posts) {
|
||||
postCount += 1;
|
||||
group = 'posts';
|
||||
}
|
||||
|
||||
return group;
|
||||
});
|
||||
|
||||
ghost.doFilter('prepostsRender', data.posts, function (posts) {
|
||||
res.render('index', {features: data.features, posts: posts, ghostGlobals: ghost.globals()});
|
||||
});
|
||||
});
|
||||
},
|
||||
'single': function (req, res) {
|
||||
ghost.dataProvider().posts.findOne({'slug': req.params.slug}, function (error, post) {
|
||||
ghost.doFilter('prePostsRender', post, function (post) {
|
||||
res.render('single', {post: post, ghostGlobals: ghost.globals()});
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
module.exports = frontendControllers;
|
||||
}());
|
47
core/frontend/helpers/index.js
Normal file
@ -0,0 +1,47 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var _ = require('underscore'),
|
||||
moment = require('moment'),
|
||||
coreHelpers;
|
||||
|
||||
coreHelpers = function (ghost) {
|
||||
|
||||
/**
|
||||
* [ description]
|
||||
* @todo ghost core helpers + a way for themes to register them
|
||||
* @param {Object} context date object
|
||||
* @param {*} block
|
||||
* @return {Object} A Moment time / date object
|
||||
*/
|
||||
ghost.registerThemeHelper('dateFormat', function (context, block) {
|
||||
var f = block.hash.format || "MMM Do, YYYY";
|
||||
return moment(context).format(f);
|
||||
});
|
||||
|
||||
/**
|
||||
* [ description]
|
||||
*
|
||||
* @param String key
|
||||
* @param String default translation
|
||||
* @param {Object} options
|
||||
* @return String A correctly internationalised string
|
||||
*/
|
||||
ghost.registerThemeHelper('e', function (key, defaultString, options) {
|
||||
var output;
|
||||
|
||||
if (ghost.config().defaultLang === 'en' && _.isEmpty(options.hash) && !ghost.config().forceI18n) {
|
||||
output = defaultString;
|
||||
} else {
|
||||
output = ghost.polyglot().t(key, options.hash);
|
||||
}
|
||||
|
||||
return output;
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
module.exports.loadCoreHelpers = coreHelpers;
|
||||
}());
|
||||
|
173
core/ghost.js
Normal file
@ -0,0 +1,173 @@
|
||||
// # Ghost Module
|
||||
// Defines core methods required to build the frontend
|
||||
|
||||
/**
|
||||
* global module,
|
||||
* require,
|
||||
* __dirname
|
||||
**/
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
// ## Setup Prerequisites
|
||||
var config = require('./../config'),
|
||||
express = require('express'),
|
||||
path = require('path'),
|
||||
hbs = require('express-hbs'),
|
||||
_ = require('underscore'),
|
||||
Polyglot = require('node-polyglot'),
|
||||
JsonDataProvider = require('./shared/models/dataProvider.json'),
|
||||
jsonDataProvider = new JsonDataProvider(),
|
||||
JugglingDataProvider = require('./shared/models/dataProvider.juggling'),
|
||||
jugglingDataProvider = new JugglingDataProvider(),
|
||||
Ghost,
|
||||
instance,
|
||||
filterCallbacks = {},
|
||||
|
||||
statuses;
|
||||
|
||||
// ## Article Statuses
|
||||
/**
|
||||
* A list of atricle status types
|
||||
* @type {Object}
|
||||
*/
|
||||
statuses = {
|
||||
'draft': 'draft',
|
||||
'complete': 'complete',
|
||||
'approved': 'approved',
|
||||
'scheduled': 'scheduled',
|
||||
'published': 'published'
|
||||
};
|
||||
|
||||
// ## Module Methods
|
||||
/**
|
||||
* @method Ghost
|
||||
* @returns {*}
|
||||
* @constructor
|
||||
*/
|
||||
Ghost = function () {
|
||||
var app,
|
||||
globals,
|
||||
polyglot;
|
||||
|
||||
if (!instance) {
|
||||
instance = this;
|
||||
|
||||
// Temporary loading of settings
|
||||
jsonDataProvider.globals.findAll(function (error, data) {
|
||||
globals = data;
|
||||
});
|
||||
|
||||
app = express();
|
||||
|
||||
polyglot = new Polyglot();
|
||||
|
||||
// functionality
|
||||
// load Plugins...
|
||||
// var f = new FancyFirstChar(ghost).init();
|
||||
|
||||
_.extend(instance, {
|
||||
app: function () { return app; },
|
||||
config: function () { return config; },
|
||||
globals: function () { return globals; }, // there's no management here to be sure this has loaded
|
||||
dataProvider: function () { return jugglingDataProvider; },
|
||||
statuses: function () { return statuses; },
|
||||
polyglot: function () { return polyglot; },
|
||||
paths: function () {
|
||||
return {
|
||||
'activeTheme': __dirname + '/../content/' + config.themeDir + '/' + config.activeTheme + '/',
|
||||
'adminViews': __dirname + '/admin/views/',
|
||||
'lang': __dirname + '/lang/'
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return instance;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {Function} fn
|
||||
* @return {method} hbs.registerHelper
|
||||
*/
|
||||
Ghost.prototype.registerThemeHelper = function (name, fn) {
|
||||
hbs.registerHelper(name, fn);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {Function} fn
|
||||
* @return {*}
|
||||
*/
|
||||
Ghost.prototype.registerTheme = function (name, fn) {};
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {Function} fn
|
||||
* @return {*}
|
||||
*/
|
||||
Ghost.prototype.registerPlugin = function (name, fn) {};
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {Function} fn
|
||||
*/
|
||||
Ghost.prototype.registerFilter = function (name, fn) {
|
||||
if (!filterCallbacks.hasOwnProperty(name)) {
|
||||
filterCallbacks[name] = [];
|
||||
}
|
||||
console.log('registering filter for ', name);
|
||||
filterCallbacks[name].push(fn);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} name [description]
|
||||
* @param {*} args
|
||||
* @param {Function} callback
|
||||
* @return {method} callback
|
||||
*/
|
||||
Ghost.prototype.doFilter = function (name, args, callback) {
|
||||
var fn;
|
||||
|
||||
if (filterCallbacks.hasOwnProperty(name)) {
|
||||
for (fn in filterCallbacks[name]) {
|
||||
if (filterCallbacks[name].hasOwnProperty(fn)) {
|
||||
console.log('doing filter for ', name);
|
||||
args = filterCallbacks[name][fn](args);
|
||||
}
|
||||
}
|
||||
}
|
||||
callback(args);
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialise Theme
|
||||
*
|
||||
* @todo Tod (?) Old comment
|
||||
* @param {Object} app
|
||||
*/
|
||||
Ghost.prototype.initTheme = function (app) {
|
||||
var self = this;
|
||||
return function initTheme(req, res, next) {
|
||||
app.set('view engine', 'hbs');
|
||||
|
||||
if (/(^\/ghost$|^\/ghost\/)/.test(req.url) === false) {
|
||||
app.engine('hbs', hbs.express3(
|
||||
{partialsDir: self.paths().activeTheme + 'partials'}
|
||||
));
|
||||
app.set('views', self.paths().activeTheme);
|
||||
} else {
|
||||
app.engine('hbs', hbs.express3({partialsDir: self.paths().adminViews + '/partials'}));
|
||||
app.set('views', self.paths().adminViews);
|
||||
app.use('/core/admin/assets', express['static'](path.join(__dirname, '/admin/assets')));
|
||||
}
|
||||
app.use(express['static'](self.paths().activeTheme));
|
||||
app.use('/content/images', express['static'](path.join(__dirname, '/../content/images')));
|
||||
|
||||
next();
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = Ghost;
|
||||
}());
|
26
core/lang/en.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"__SECTION__": "admin core",
|
||||
"admin.navbar.dashboard": "Dashboard",
|
||||
"admin.navbar.blog": "Blog",
|
||||
"admin.navbar.settings": "Settings",
|
||||
|
||||
"__SECTION__": "icons",
|
||||
"icon.category.label": "Category",
|
||||
"icon.faq.label": "?",
|
||||
"icon.faq.markdown.title": "What is Markdown?",
|
||||
"icon.full_screen.label": "Full Screen",
|
||||
"icon.full_screen.title": "Enter full screen mode",
|
||||
"icon.settings.label": "Settings",
|
||||
|
||||
"__SECTION__": "editor",
|
||||
"editor.entry_title.placeholder": "The Post Title Gets Inserted Up Here",
|
||||
"editor.entry_permalink.label": "Permalink:",
|
||||
"editor.entry_permalink.example_url": "http://yoursite.com/",
|
||||
"editor.entry_permalink.example_slug": "the-post-title-goes-here",
|
||||
"editor.headers.markdown.label": "Markdown",
|
||||
"editor.headers.preview.label": "Preview",
|
||||
"editor.word_count": "%{count} words",
|
||||
"editor.actions.save_draft": "Save Draft",
|
||||
"editor.actions.publish": "Publish"
|
||||
|
||||
}
|
26
core/lang/en_PL.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"__SECTION__": "admin core",
|
||||
"admin.navbar.dashboard": "Ashboarday",
|
||||
"admin.navbar.blog": "Logbay",
|
||||
"admin.navbar.settings": "Ettingsay",
|
||||
|
||||
"__SECTION__": "icons",
|
||||
"icon.category.label": "Ategorycay",
|
||||
"icon.faq.label": "?",
|
||||
"icon.faq.markdown.title": "Atwhay isway Arkdownmay",
|
||||
"icon.full_screen.label": "Ullfay Eenscray",
|
||||
"icon.full_screen.title": "Enterway ullfay eenscrayodemay",
|
||||
"icon.settings.label": "Ettingssay",
|
||||
|
||||
"__SECTION__": "editor",
|
||||
"editor.entry_title.placeholder": "Ethay Ostpay Itletay Etsgay Insertedway Upway Erehay",
|
||||
"editor.entry_permalink.label": "Ermalinkpay:",
|
||||
"editor.entry_permalink.example_url": "http://oursiteyay.omcay/",
|
||||
"editor.entry_permalink.example_slug": "ethay-ostpay-itletay-oesgay-erehay",
|
||||
"editor.headers.markdown.label": "Arkdownmay",
|
||||
"editor.headers.preview.label": "Eviewpray",
|
||||
"editor.word_count": "%{count} ordsway",
|
||||
"editor.actions.save_draft": "Avesay Aftdray",
|
||||
"editor.actions.publish": "Ublishpay"
|
||||
|
||||
}
|
54
core/lang/i18n.js
Normal file
@ -0,0 +1,54 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var fs = require('fs'),
|
||||
/**
|
||||
* Create new Polyglot object
|
||||
* @type {Polyglot}
|
||||
*/
|
||||
I18n;
|
||||
|
||||
I18n = function (ghost) {
|
||||
|
||||
// TODO: validate
|
||||
var lang = ghost.config().defaultLang,
|
||||
path = ghost.paths().lang,
|
||||
langFilePath = path + lang + '.json';
|
||||
|
||||
return function (req, res, next) {
|
||||
|
||||
if (lang === 'en') {
|
||||
// TODO: do stuff here to optimise for en
|
||||
}
|
||||
|
||||
/** TODO potentially use req.acceptedLanguages rather than the default
|
||||
* TODO handle loading language file for frontend on frontend request etc
|
||||
* TODO switch this mess to be promise driven */
|
||||
fs.stat(langFilePath, function (error, stat) {
|
||||
if (error) {
|
||||
console.log('No language file found for language ' + lang + '. Defaulting to en');
|
||||
lang = 'en';
|
||||
}
|
||||
|
||||
fs.readFile(langFilePath, function (error, data) {
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
try {
|
||||
data = JSON.parse(data);
|
||||
} catch (e) {
|
||||
throw e; // TODO - do something better with the error here
|
||||
}
|
||||
|
||||
ghost.polyglot().extend(data);
|
||||
|
||||
next();
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
module.exports.load = I18n;
|
||||
}());
|
24
core/shared/data/fixtures/posts.json
Normal file
20
core/shared/data/fixtures/settings.json
Normal file
@ -0,0 +1,20 @@
|
||||
[
|
||||
{
|
||||
"key": "url",
|
||||
"value": "http://localhost:3333",
|
||||
"createdBy": 1,
|
||||
"updatedBy": 1
|
||||
},
|
||||
{
|
||||
"key": "title",
|
||||
"value": "John O'Nolan",
|
||||
"createdBy": 1,
|
||||
"updatedBy": 1
|
||||
},
|
||||
{
|
||||
"key": "description",
|
||||
"value": "Interactive designer, public speaker, startup advisor and writer. Living in Austria, attempting world domination via keyboard.",
|
||||
"createdBy": 1,
|
||||
"updatedBy": 1
|
||||
}
|
||||
]
|
15
core/shared/data/fixtures/users.json
Normal file
@ -0,0 +1,15 @@
|
||||
[
|
||||
{
|
||||
"id": "1",
|
||||
"username": "johnonolan",
|
||||
"firstName": "John",
|
||||
"lastName": "O'Nolan",
|
||||
"emailAddress": "john@onolan.org",
|
||||
"profilePicture": "logo.png",
|
||||
"coverPicture": "",
|
||||
"bio": "Interactive designer, public speaker, startup advisor and writer. Living in Austria, attempting world domination via keyboard.",
|
||||
"url": "john.onolan.org",
|
||||
"createdBy": 1,
|
||||
"updatedBy": 1
|
||||
}
|
||||
]
|
52
core/shared/models/dataProvider.json.js
Normal file
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Dummy dataProvider returns hardcoded JSON data until we finish migrating settings data to a datastore
|
||||
*/
|
||||
|
||||
/*globals module, require */
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var _ = require('underscore'),
|
||||
|
||||
DataProvider,
|
||||
blogData,
|
||||
instance,
|
||||
d;
|
||||
|
||||
blogData = {
|
||||
url: 'http://localhost:3333', //'http://john.onolan.org',
|
||||
title: "John O'Nolan",
|
||||
description: "Interactive designer, public speaker, startup advisor and writer. Living in Austria, attempting world domination via keyboard."
|
||||
};
|
||||
|
||||
DataProvider = function () {
|
||||
if (!instance) {
|
||||
instance = this;
|
||||
}
|
||||
|
||||
return instance;
|
||||
};
|
||||
DataProvider.prototype.globals = {};
|
||||
DataProvider.prototype.globals.data = [];
|
||||
|
||||
|
||||
DataProvider.prototype.globals.findAll = function (callback) {
|
||||
callback(null, this.data);
|
||||
};
|
||||
|
||||
DataProvider.prototype.globals.save = function (globals, callback) {
|
||||
var self = this;
|
||||
|
||||
_.each(globals, function (global, key) {
|
||||
self.data[key] = global;
|
||||
});
|
||||
|
||||
callback(null, globals);
|
||||
};
|
||||
|
||||
/* Lets bootstrap with dummy data */
|
||||
d = new DataProvider();
|
||||
d.globals.save(blogData, function (error, globals) {});
|
||||
|
||||
module.exports = DataProvider;
|
||||
}());
|
139
core/shared/models/dataProvider.juggling.js
Normal file
@ -0,0 +1,139 @@
|
||||
/**
|
||||
* Provides access to data via the JugglingDb ORM
|
||||
*/
|
||||
|
||||
/*globals module, require */
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var schema = require('./schema').schema,
|
||||
fs = require('fs'),
|
||||
_ = require('underscore'),
|
||||
DataProvider,
|
||||
instance;
|
||||
|
||||
|
||||
function populateData(callback) {
|
||||
// TODO: convert to promises
|
||||
schema.models.Setting.findOne({}, function (error, data) {
|
||||
if (data === null) {
|
||||
// we haven't loaded any data yet
|
||||
fs.readFile(__dirname + '/data/fixtures/users.json', function (error, data) {
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
var users = JSON.parse(data);
|
||||
|
||||
_.each(users, function (post) {
|
||||
schema.models.User.create(post, function (error, data) {
|
||||
console.log('User created error', error);
|
||||
console.log('User created data', data);
|
||||
});
|
||||
});
|
||||
|
||||
fs.readFile(__dirname + '/data/fixtures/posts.json', function (error, data) {
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
var posts = JSON.parse(data),
|
||||
post;
|
||||
|
||||
_.each(posts, function (_post) {
|
||||
post = new schema.models.Post(_post);
|
||||
|
||||
post.preCreate(function () {
|
||||
post.save(function (error, data) {
|
||||
console.log('Post created error', error);
|
||||
console.log('Post created data', data);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
fs.readFile(__dirname + '/data/fixtures/settings.json', function (error, data) {
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
var posts = JSON.parse(data);
|
||||
|
||||
_.each(posts, function (post) {
|
||||
schema.models.Setting.create(post, function (error, data) {
|
||||
console.log('Setting created error', error);
|
||||
console.log('Setting created data', data);
|
||||
});
|
||||
});
|
||||
|
||||
callback();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
DataProvider = function () {
|
||||
if (!instance) {
|
||||
instance = this;
|
||||
|
||||
if (process.env.forcePopulate) {
|
||||
populateData();
|
||||
}
|
||||
}
|
||||
|
||||
return instance;
|
||||
};
|
||||
|
||||
DataProvider.prototype.posts = function () {};
|
||||
|
||||
/**
|
||||
* Naive find all
|
||||
* @param callback
|
||||
*/
|
||||
DataProvider.prototype.posts.findAll = function (callback) {
|
||||
schema.models.Post.all(callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Naive find one where args match
|
||||
* @param callback
|
||||
*/
|
||||
DataProvider.prototype.posts.findOne = function (args, callback) {
|
||||
schema.models.Post.findOne({where: args}, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Naive add
|
||||
* @param post
|
||||
* @param callback
|
||||
*/
|
||||
DataProvider.prototype.posts.add = function (_post, callback) {
|
||||
var post = new schema.models.Post(_post);
|
||||
|
||||
post.preCreate(function () {
|
||||
post.save(callback);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Naive edit
|
||||
* @param post
|
||||
* @param callback
|
||||
*/
|
||||
DataProvider.prototype.posts.edit = function (_post, callback) {
|
||||
schema.models.Post.findOne({where: {id: _post.id}}, function (error, post) {
|
||||
post = _.extend(post, _post);
|
||||
|
||||
schema.models.Post.updateOrCreate(post, callback);
|
||||
});
|
||||
};
|
||||
|
||||
DataProvider.prototype.populateData = populateData;
|
||||
|
||||
module.exports = DataProvider;
|
||||
}());
|
111
core/shared/models/schema.js
Normal file
@ -0,0 +1,111 @@
|
||||
/**
|
||||
* Database Schema, created with JugglingDB
|
||||
*
|
||||
* Vastly incomplete!
|
||||
*/
|
||||
|
||||
/*globals module, require */
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var Schema = require('jugglingdb').Schema,
|
||||
schema = new Schema('sqlite3', {
|
||||
database: __dirname + '/../data/datastore.db'
|
||||
}),
|
||||
Post,
|
||||
User,
|
||||
Setting;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
POST / Post / Posts
|
||||
------------------------------------------------------------------------------------*/
|
||||
Post = schema.define('Post', {
|
||||
title: String,
|
||||
slug: String,
|
||||
content: Schema.Text,
|
||||
contentHtml: Schema.Text,
|
||||
featured: Boolean,
|
||||
image: String,
|
||||
status: String,
|
||||
language: String,
|
||||
createdAt: Date,
|
||||
createdBy: Number,
|
||||
updatedAt: Date,
|
||||
updatedBy: Number
|
||||
});
|
||||
|
||||
Post.prototype.generateSlug = function () {
|
||||
return this.title.replace(/\:/g, '').replace(/\s/g, '-').toLowerCase();
|
||||
};
|
||||
|
||||
Post.prototype.preCreate = function (next) {
|
||||
console.log('pre create 1', this);
|
||||
|
||||
if (this.createdAt === undefined) {
|
||||
this.createdAt = new Date();
|
||||
}
|
||||
if (this.slug === undefined) {
|
||||
this.slug = this.generateSlug();
|
||||
}
|
||||
|
||||
console.log('pre create 2', this);
|
||||
next();
|
||||
};
|
||||
|
||||
// Validations
|
||||
Post.validatesPresenceOf('title', {message: 'Post title cannot be blank'});
|
||||
//Post.validatesPresenceOf('slug');
|
||||
//Post.validatesPresenceOf('language', {message: 'Language cannot be blank'});
|
||||
//Post.validatesUniquenessOf('slug');
|
||||
//Post.validatesLengthOf('language', {min: 2, max: 5}, "The language code should be between 2 and 5 chars long, E.g. 'en' or 'en_GB' ");
|
||||
|
||||
|
||||
Post.beforeSave = function (next, data) {
|
||||
console.log('before s1', data);
|
||||
// set updated
|
||||
data.updatedAt = new Date();
|
||||
next();
|
||||
};
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
USER / User / Users
|
||||
------------------------------------------------------------------------------------*/
|
||||
User = schema.define('User', {
|
||||
username: String,
|
||||
firstName: String,
|
||||
lastName: String,
|
||||
emailAddress: String,
|
||||
profilePicture: String,
|
||||
coverPicture: String,
|
||||
bio: Schema.Text,
|
||||
url: String,
|
||||
createdAt: Date,
|
||||
createdBy: Number,
|
||||
updatedAt: Date,
|
||||
updatedBy: Number
|
||||
});
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
SETTING / Setting / Settings
|
||||
------------------------------------------------------------------------------------*/
|
||||
Setting = schema.define('Setting', {
|
||||
key: String,
|
||||
value: Schema.Text,
|
||||
createdAt: Date,
|
||||
createdBy: Number,
|
||||
updatedAt: Date,
|
||||
updatedBy: Number
|
||||
});
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
RELATIONSHIPS
|
||||
------------------------------------------------------------------------------------*/
|
||||
User.hasMany(Post, {as: 'posts', foreignKey: 'createdBy'});
|
||||
Post.belongsTo(User, {as: 'author', foreignKey: 'createdBy'});
|
||||
|
||||
schema.autoupdate();
|
||||
|
||||
exports.schema = schema;
|
||||
}());
|
16
core/test/ghost/test-dataProvider.json.js
Normal file
@ -0,0 +1,16 @@
|
||||
/*global require, module */
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var DataProvider = require('../../shared/models/dataProvider.json');
|
||||
|
||||
module.exports = {
|
||||
'singleton': function (test) {
|
||||
var provider1 = new DataProvider(),
|
||||
provider2 = new DataProvider();
|
||||
|
||||
test.equal(provider1, provider2);
|
||||
test.done();
|
||||
}
|
||||
};
|
||||
}());
|
16
core/test/ghost/test-ghost.js
Normal file
@ -0,0 +1,16 @@
|
||||
/*global require, module */
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var Ghost = require('../../ghost');
|
||||
|
||||
module.exports = {
|
||||
'singleton': function (test) {
|
||||
var ghost1 = new Ghost(),
|
||||
ghost2 = new Ghost();
|
||||
|
||||
test.equal(ghost1, ghost2);
|
||||
test.done();
|
||||
}
|
||||
};
|
||||
}());
|
252
core/test/html/dashboard.html
Normal file
@ -0,0 +1,252 @@
|
||||
<!doctype html>
|
||||
|
||||
<!--[if lt IE 7]><html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
|
||||
<!--[if (IE 7)&!(IEMobile)]><html class="no-js lt-ie9 lt-ie8" lang="en"><![endif]-->
|
||||
<!--[if (IE 8)&!(IEMobile)]><html class="no-js lt-ie9" lang="en"><![endif]-->
|
||||
|
||||
<head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Ghost</title>
|
||||
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<meta name="HandheldFriendly" content="True">
|
||||
<meta name="MobileOptimized" content="320">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<!-- For all browsers -->
|
||||
<link rel="stylesheet" href="../core/admin/assets/css/screen.css">
|
||||
|
||||
<link rel="shortcut icon" href="/favicon.ico">
|
||||
<link rel="logo" type="image/svg" href="assets/images/logo.svg"/>
|
||||
<meta http-equiv="cleartype" content="on">
|
||||
|
||||
</head>
|
||||
|
||||
<body class="dashboard">
|
||||
|
||||
<header id="global-header" class="navbar">
|
||||
<a id="ghost" class="icon-ghost" href="#"><span class="hidden">Ghost</span></a>
|
||||
<nav id="global-nav" role="navigation">
|
||||
<ul id="main-menu">
|
||||
<li class="active"><a href="#">Dashboard</a></li>
|
||||
<li><a href="#">Blog</a></li>
|
||||
<li><a href="#">Pages</a></li>
|
||||
<li><a href="#">Settings</a></li>
|
||||
<li id="user-menu" class="subnav">
|
||||
<a href="#" data-toggle="ul">
|
||||
<img class="avatar" src="assets/img/user.jpg" alt="Avatar" />
|
||||
<span class="name">John O'Nolan</span>
|
||||
</a>
|
||||
<ul>
|
||||
<li><a href="#">Your Profile</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#">Help / Support</a></li>
|
||||
<li><a href="#">Keyboard Shortcuts</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#">Sign Out</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main role="main">
|
||||
|
||||
<section class="dashboard-controls">
|
||||
<div class="text left"><strong>Welcome back</strong>, John.</div>
|
||||
<nav class="controls-nav">
|
||||
<ul class="nav inline">
|
||||
<li><a href="#"><span class="icon-new"></span> New Post</a></li>
|
||||
<li><a href="#"><span class="icon-users"></span> Authors</a></li>
|
||||
<li><a href="#"><span class="icon-analytics"></span> Analytics</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="text right"><a href="#"><span class="icon-settings"></span><span class="hidden">Settings</span></a></div>
|
||||
<div class="clearfix"></div><!--TODO: replace this later with something less shit-->
|
||||
</section>
|
||||
|
||||
<section class="widget time-date">
|
||||
<header>
|
||||
London, United Kingdom
|
||||
</header>
|
||||
<section class="content">
|
||||
<div class="time">
|
||||
8:55<span>am</span>
|
||||
</div>
|
||||
<div class="date"><!--TODO: convert to html5 <date>-->
|
||||
<span>Wednesday</span>
|
||||
13 June 2012
|
||||
</div>
|
||||
</section>
|
||||
<footer>
|
||||
Timezone: UTC +1
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
<section class="widget">
|
||||
<header>
|
||||
Top Authors This Month
|
||||
</header>
|
||||
<section class="content">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>Posts</td>
|
||||
<td>Comments</td>
|
||||
<td>tweets</td>
|
||||
<td>Likes</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><strong class="text-uppercase"><img class="user-img" src="assets/img/user.jpg" width="34px" height="34px" alt=""> John</strong></td>
|
||||
<td><strong class="callout">32</strong> <span>Posts</span></td>
|
||||
<td><strong>231</strong> <span>Comments</span></td>
|
||||
<td><strong>103</strong> <span>tweets</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong class="text-uppercase"><img class="user-img" src="assets/img/user.jpg" width="34px" height="34px" alt=""> James</strong></td>
|
||||
<td><strong>32</strong> <span>Posts</span></td>
|
||||
<td><strong class="callout">231</strong> <span>Comments</span></td>
|
||||
<td><strong>103</strong> <span>tweets</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong class="text-uppercase"><img class="user-img" src="assets/img/user.jpg" width="34px" height="34px" alt=""> Jerry</strong></td>
|
||||
<td><strong>32</strong> <span>Posts</span></td>
|
||||
<td><strong>231</strong> <span>Comments</span></td>
|
||||
<td><strong class="callout">103</strong> <span>tweets</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<footer>
|
||||
Ghost Stats
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
<section class="widget post-statuses">
|
||||
<header>
|
||||
Post Statuses
|
||||
</header>
|
||||
<section class="content">
|
||||
<div class="status-levels left">
|
||||
<div class="scheduled" style="height: 30px;">Scheduled</div>
|
||||
<div class="pending" style="height: 50px;">Pending</div>
|
||||
<div class="draft" style="height: 60px;">Draft</div>
|
||||
</div>
|
||||
<div class="status-text left">
|
||||
<div class="scheduled"><strong>5</strong> Scheduled</div>
|
||||
<div class="pending"><strong>12</strong> Pending</div>
|
||||
<div class="draft"><strong>32</strong> Draft</div>
|
||||
</div>
|
||||
</section>
|
||||
<footer>
|
||||
Ghost Stats
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
<section class="widget total-views">
|
||||
<header>
|
||||
Total Page Views (Last 30 Days)
|
||||
</header>
|
||||
<section class="content">
|
||||
<div class="widget-stats">
|
||||
<span>37,921</span>
|
||||
<span>
|
||||
Previous <strong>32,419</strong> / <strong class="positive-text">+15.4%</strong>
|
||||
</span>
|
||||
</div>
|
||||
</section>
|
||||
<footer>
|
||||
Google Analytics
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
<section class="widget live-visitors">
|
||||
<header>
|
||||
Live Visitors
|
||||
</header>
|
||||
<section class="content">
|
||||
<div class="widget-stats">
|
||||
<span>124</span>
|
||||
<span>
|
||||
<strong>391</strong> max this month
|
||||
</span>
|
||||
</div>
|
||||
</section>
|
||||
<footer>
|
||||
Woopra
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
<section class="widget">
|
||||
<header>
|
||||
Twitter Followers
|
||||
</header>
|
||||
<section class="content">
|
||||
<div class="widget-stats">
|
||||
<span>12,304</span>
|
||||
<span>
|
||||
<strong class="positive-text">+123</strong> this month
|
||||
</span>
|
||||
</div>
|
||||
</section>
|
||||
<footer>
|
||||
@ghost
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
<section class="widget todays-traffic">
|
||||
<header>
|
||||
Today’s Traffic (Actions)
|
||||
</header>
|
||||
<section class="content">
|
||||
<ul class="nav">
|
||||
<li>
|
||||
<div>Post Title Excerpt Which is Li... <strong class="right">327</strong></div>
|
||||
</li>
|
||||
<li>
|
||||
<div>My homepage <strong class="right">327</strong></div>
|
||||
</li>
|
||||
<li>
|
||||
<div>Another long ass post about som... <strong class="right">327</strong></div>
|
||||
</li>
|
||||
<li>
|
||||
<div>Boracay time! <strong class="right">327</strong></div>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
<footer>
|
||||
Woopra
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
<section class="widget">
|
||||
<header>
|
||||
Total Likes
|
||||
</header>
|
||||
<section class="content">
|
||||
<div class="widget-stats">
|
||||
<span>6,931</span>
|
||||
<span>
|
||||
<strong class="negative-text">-23</strong> this month
|
||||
</span>
|
||||
</div>
|
||||
</section>
|
||||
<footer>
|
||||
Facebook
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<script type="text/javascript" src="assets/js/jquery.js"></script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
51
core/test/html/login.html
Normal file
@ -0,0 +1,51 @@
|
||||
<!doctype html>
|
||||
|
||||
<!--[if lt IE 7]><html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
|
||||
<!--[if (IE 7)&!(IEMobile)]><html class="no-js lt-ie9 lt-ie8" lang="en"><![endif]-->
|
||||
<!--[if (IE 8)&!(IEMobile)]><html class="no-js lt-ie9" lang="en"><![endif]-->
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Ghost</title>
|
||||
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<meta name="HandheldFriendly" content="True">
|
||||
<meta name="MobileOptimized" content="320">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<!-- For all browsers -->
|
||||
<link rel="stylesheet" href="../core/admin/assets/css/screen.css">
|
||||
|
||||
<link rel="shortcut icon" href="/favicon.ico">
|
||||
<link rel="logo" type="image/svg" href="assets/images/logo.svg"/>
|
||||
<meta http-equiv="cleartype" content="on">
|
||||
|
||||
</head>
|
||||
|
||||
<body class="ghost-login">
|
||||
|
||||
<header id="login-header">
|
||||
|
||||
</header>
|
||||
|
||||
<main role="main">
|
||||
<img class="login-logo" src="../core/admin/assets/img/logo.png" alt="" />
|
||||
<form id="login" action="#">
|
||||
<div class="email-wrap">
|
||||
<input class="email" type="text" placeholder="Email Address">
|
||||
</div>
|
||||
<div class="password-wrap">
|
||||
<input class="password" type="password" placeholder="Password">
|
||||
</div>
|
||||
<button class="button-save" type="submit">Log in</button>
|
||||
</form>
|
||||
</main>
|
||||
|
||||
<script type="text/javascript" src="assets/js/jquery.js"></script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
221
core/test/html/manage.html
Normal file
@ -0,0 +1,221 @@
|
||||
<!doctype html>
|
||||
|
||||
<!--[if lt IE 7]><html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
|
||||
<!--[if (IE 7)&!(IEMobile)]><html class="no-js lt-ie9 lt-ie8" lang="en"><![endif]-->
|
||||
<!--[if (IE 8)&!(IEMobile)]><html class="no-js lt-ie9" lang="en"><![endif]-->
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Ghost</title>
|
||||
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<meta name="HandheldFriendly" content="True">
|
||||
<meta name="MobileOptimized" content="320">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<!-- For all browsers -->
|
||||
<link rel="stylesheet" href="../core/admin/assets/css/screen.css">
|
||||
|
||||
<link rel="shortcut icon" href="/favicon.ico">
|
||||
<link rel="logo" type="image/svg" href="assets/images/logo.svg"/>
|
||||
<meta http-equiv="cleartype" content="on">
|
||||
|
||||
</head>
|
||||
|
||||
<body class="manage">
|
||||
|
||||
<header id="global-header" class="navbar">
|
||||
<a id="ghost" class="icon-ghost" href="#"><span class="hidden">Ghost</span></a>
|
||||
<nav id="global-nav" role="navigation">
|
||||
<ul id="main-menu">
|
||||
<li class="active"><a href="#">Dashboard</a></li>
|
||||
<li><a href="#">Blog</a></li>
|
||||
<li><a href="#">Pages</a></li>
|
||||
<li><a href="#">Settings</a></li>
|
||||
<li id="user-menu" class="subnav">
|
||||
<a href="#" data-toggle="ul">
|
||||
<img class="avatar" src="assets/img/user.jpg" alt="Avatar" />
|
||||
<span class="name">John O'Nolan</span>
|
||||
</a>
|
||||
<ul>
|
||||
<li><a href="#">Your Profile</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#">Help / Support</a></li>
|
||||
<li><a href="#">Keyboard Shortcuts</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#">Sign Out</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main role="main">
|
||||
|
||||
<div class="half-wrap left-panel">
|
||||
<section class="box manage-posts">
|
||||
<header>
|
||||
Blog Posts <a href="#" class="right search">Search</a>
|
||||
</header>
|
||||
<ol class="post-list">
|
||||
<li>
|
||||
<a class="permalink" href="#">
|
||||
<figure class="thumbnail"><img src="assets/img/user.jpg" alt="img" /></figure>
|
||||
<h3 class="entry-title">Ut Enim ad Minim Veniam Quis Nostrud</h3>
|
||||
<section class="entry-meta">
|
||||
<time datetime="2013-01-04" class="date">Today</time>
|
||||
<span class="category">News, Category</span>
|
||||
<span class="views">1,934</span>
|
||||
</section>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="permalink" href="#">
|
||||
<figure class="thumbnail"><img src="assets/img/user.jpg" alt="img" /></figure>
|
||||
<h3 class="entry-title">Ut Enim ad Minim Veniam Quis Nostrud Exercitation Ullamco</h3>
|
||||
<section class="entry-meta">
|
||||
<time datetime="2013-01-04" class="date">Today</time>
|
||||
<span class="category">News, Category</span>
|
||||
<span class="views">1,934</span>
|
||||
</section>
|
||||
</a>
|
||||
</li>
|
||||
<li class="current featured">
|
||||
<a class="permalink" href="#">
|
||||
<figure class="thumbnail"><img src="assets/img/user.jpg" alt="img" /></figure>
|
||||
<h3 class="entry-title">Ut Enim ad Minim Veniam Quis Nostrud Exercitation Ullamco</h3>
|
||||
<section class="entry-meta">
|
||||
<time datetime="2013-01-04" class="date">Today</time>
|
||||
<span class="category">News, Category</span>
|
||||
<span class="views">1,934</span>
|
||||
</section>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="permalink" href="#">
|
||||
<figure class="thumbnail"><img src="assets/img/user.jpg" alt="img" /></figure>
|
||||
<h3 class="entry-title">Ut Enim ad Minim Veniam Quis Nostrud Exercitation Ullamco</h3>
|
||||
<section class="entry-meta">
|
||||
<time datetime="2013-01-04" class="date">Today</time>
|
||||
<span class="category">News, Category</span>
|
||||
<span class="views">1,934</span>
|
||||
</section>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="permalink" href="#">
|
||||
<figure class="thumbnail"><img src="assets/img/user.jpg" alt="img" /></figure>
|
||||
<h3 class="entry-title">Ut Enim ad Minim Veniam Quis Nostrud Exercitation Ullamco</h3>
|
||||
<section class="entry-meta">
|
||||
<time datetime="2013-01-04" class="date">Today</time>
|
||||
<span class="category">News, Category</span>
|
||||
<span class="views">1,934</span>
|
||||
</section>
|
||||
</a>
|
||||
</li>
|
||||
<li class="featured">
|
||||
<a class="permalink" href="#">
|
||||
<figure class="thumbnail"><img src="assets/img/user.jpg" alt="img" /></figure>
|
||||
<h3 class="entry-title">Ut Enim ad Minim Veniam Quis Nostrud Exercitation Ullamco</h3>
|
||||
<section class="entry-meta">
|
||||
<time datetime="2013-01-04" class="date">Today</time>
|
||||
<span class="category">News, Category</span>
|
||||
<span class="views">1,934</span>
|
||||
</section>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="permalink" href="#">
|
||||
<figure class="thumbnail"><img src="assets/img/user.jpg" alt="img" /></figure>
|
||||
<h3 class="entry-title">Ut Enim ad Minim Veniam Quis Nostrud Exercitation Ullamco</h3>
|
||||
<section class="entry-meta">
|
||||
<time datetime="2013-01-04" class="date">Today</time>
|
||||
<span class="category">News, Category</span>
|
||||
<span class="views">1,934</span>
|
||||
</section>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="permalink" href="#">
|
||||
<figure class="thumbnail"></figure>
|
||||
<h3 class="entry-title">Ut Enim ad Minim Veniam Quis Nostrud Exercitation Ullamco</h3>
|
||||
<section class="entry-meta">
|
||||
<time datetime="2013-01-04" class="date">Today</time>
|
||||
<span class="category">News, Category</span>
|
||||
<span class="views">1,934</span>
|
||||
</section>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="permalink" href="#">
|
||||
<figure class="thumbnail"><img src="assets/img/user.jpg" alt="img" /></figure>
|
||||
<h3 class="entry-title">Ut Enim ad Minim Veniam Quis Nostrud Exercitation Ullamco</h3>
|
||||
<section class="entry-meta">
|
||||
<time datetime="2013-01-04" class="date">Today</time>
|
||||
<span class="category">News, Category</span>
|
||||
<span class="views">1,934</span>
|
||||
</section>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="half-wrap right-panel">
|
||||
<section class="box preview-post featured">
|
||||
<header>
|
||||
Published + Featured
|
||||
<section class="right">
|
||||
<ul class="post-utility">
|
||||
<li><a class="edit" href="#">Edit</a></li>
|
||||
<li><a class="view" href="#">View</a></li>
|
||||
<li><a class="delete" href="#">Delete</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
</header>
|
||||
<section class="post-content">
|
||||
<h2>Ut Enim ad Minim Veniam Quis Nostrud Exercitation Ullamco</h2>
|
||||
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis <a href="#">parturient</a> montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu.</p>
|
||||
|
||||
<h2>This is a Heading 2</h2>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod <strong>tempor incididunt</strong> ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod <strong>tempor incididunt</strong> ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipisicing elit, Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. sed do eiusmod <strong>tempor incididunt</strong> ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod <strong>tempor incididunt</strong> ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod <strong>tempor incididunt</strong> ut labore et dolore magna aliqua.</p>
|
||||
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
|
||||
|
||||
<img src="assets/img/postimg.jpg" alt="" />
|
||||
|
||||
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim.</p>
|
||||
|
||||
<ul>
|
||||
<li>Lorem ipsum dolor sit amet</li>
|
||||
<li>Lorem ipsum dolor sit amet</li>
|
||||
<li>Lorem ipsum dolor sit amet</li>
|
||||
<li>Lorem ipsum dolor sit amet</li>
|
||||
<li>Lorem ipsum dolor sit amet</li>
|
||||
</ul>
|
||||
|
||||
<h3>This is a Heading 3</h3>
|
||||
|
||||
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
|
||||
|
||||
<ol>
|
||||
<li>Lorem ipsum dolor sit amet</li>
|
||||
<li>Lorem ipsum dolor sit amet</li>
|
||||
<li>Lorem ipsum dolor sit amet</li>
|
||||
<li>Lorem ipsum dolor sit amet</li>
|
||||
<li>Lorem ipsum dolor sit amet</li>
|
||||
</ol>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
|
||||
<script type="text/javascript" src="assets/js/jquery.js"></script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
191
core/test/html/notifications.html
Normal file
@ -0,0 +1,191 @@
|
||||
<!doctype html>
|
||||
|
||||
<!--[if lt IE 7]><html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
|
||||
<!--[if (IE 7)&!(IEMobile)]><html class="no-js lt-ie9 lt-ie8" lang="en"><![endif]-->
|
||||
<!--[if (IE 8)&!(IEMobile)]><html class="no-js lt-ie9" lang="en"><![endif]-->
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Ghost</title>
|
||||
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<meta name="HandheldFriendly" content="True">
|
||||
<meta name="MobileOptimized" content="320">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<!-- For all browsers -->
|
||||
<link rel="stylesheet" href="../core/admin/assets/css/screen.css">
|
||||
|
||||
<link rel="shortcut icon" href="/favicon.ico">
|
||||
<link rel="logo" type="image/svg" href="assets/images/logo.svg"/>
|
||||
<meta http-equiv="cleartype" content="on">
|
||||
|
||||
</head>
|
||||
|
||||
<body class="editor">
|
||||
|
||||
<header id="global-header" class="navbar">
|
||||
<a id="ghost" class="icon-ghost" href="#"><span class="hidden">Ghost</span></a>
|
||||
<nav id="global-nav" role="navigation">
|
||||
<ul id="main-menu">
|
||||
<li><a href="#">Dashboard</a></li>
|
||||
<li class="active"><a href="#">Blog</a></li>
|
||||
<li><a href="#">Pages</a></li>
|
||||
<li><a href="#">Settings</a></li>
|
||||
<li id="user-menu" class="subnav">
|
||||
<a href="#" data-toggle="ul">
|
||||
<img class="avatar" src="assets/img/user.jpg" alt="Avatar" />
|
||||
<span class="name">John O'Nolan</span>
|
||||
</a>
|
||||
<ul>
|
||||
<li><a href="#">Your Profile</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#">Help / Support</a></li>
|
||||
<li><a href="#">Keyboard Shortcuts</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#">Sign Out</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main role="main">
|
||||
|
||||
<section class="notification">
|
||||
This is a general notification. The default. Gets your attention. Tells you stuff.
|
||||
<a class="close" href="#"><span class="hidden">Close</span></a>
|
||||
</section>
|
||||
|
||||
<section class="notification-success">
|
||||
The action you attempted completed successfully.
|
||||
<a class="close" href="#"><span class="hidden">Close</span></a>
|
||||
</section>
|
||||
|
||||
<section class="notification-alert">
|
||||
General information. Yay.
|
||||
<a class="close" href="#"><span class="hidden">Close</span></a>
|
||||
</section>
|
||||
|
||||
<section class="notification-error">
|
||||
You done fucked up good.
|
||||
<a class="close" href="#"><span class="hidden">Close</span></a>
|
||||
</section>
|
||||
|
||||
<header>
|
||||
<section class="box entry-title">
|
||||
<input type="text" placeholder="The Post Title Gets Inserted Up Here">
|
||||
<a class="icon-fullscreen" href="#" title="Enter full screen mode"><span class="hidden">Full Screen</span></a>
|
||||
</section>
|
||||
<span class="entry-permalink"><strong>Permalink:</strong> http://yoursite.com/<strong>the-post-title-goes-here</strong>/</span>
|
||||
</header>
|
||||
|
||||
<div class="wrapper">
|
||||
<div class="half-wrap">
|
||||
<section class="box entry-content active">
|
||||
<header>
|
||||
Markdown <a href="#" title="What is Markdown?" class="right icon-faq"><span class="hidden">?</span></a>
|
||||
</header>
|
||||
<textarea class="markdown">
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu.
|
||||
|
||||
##This is a Heading 2
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim.
|
||||
|
||||
* Lorem ipsum dolor sit amet
|
||||
* Lorem ipsum dolor sit amet
|
||||
* Lorem ipsum dolor sit amet
|
||||
* Lorem ipsum dolor sit amet
|
||||
* Lorem ipsum dolor sit amet
|
||||
|
||||
###This is a Heading 3
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
|
||||
|
||||
1. Lorem ipsum dolor sit amet
|
||||
2. Lorem ipsum dolor sit amet
|
||||
3. Lorem ipsum dolor sit amet
|
||||
4. Lorem ipsum dolor sit amet
|
||||
5. Lorem ipsum dolor sit amet
|
||||
|
||||
</textarea>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="half-wrap">
|
||||
<section class="box entry-preview">
|
||||
<header>
|
||||
Preview <span class="right">561 words</span>
|
||||
</header>
|
||||
<section class="entry-preview-content">
|
||||
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis <a href="#">parturient</a> montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu.</p>
|
||||
|
||||
<h2>This is a Heading 2</h2>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod <strong>tempor incididunt</strong> ut labore et dolore magna aliqua.</p>
|
||||
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
|
||||
|
||||
<div class="img-placeholder">
|
||||
<span>Drag image here - or <a href="#" class="btn btn-light btn-rounded">Upload</a></span>
|
||||
</div>
|
||||
|
||||
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim.</p>
|
||||
|
||||
<ul>
|
||||
<li>Lorem ipsum dolor sit amet</li>
|
||||
<li>Lorem ipsum dolor sit amet</li>
|
||||
<li>Lorem ipsum dolor sit amet</li>
|
||||
<li>Lorem ipsum dolor sit amet</li>
|
||||
<li>Lorem ipsum dolor sit amet</li>
|
||||
</ul>
|
||||
|
||||
<h3>This is a Heading 3</h3>
|
||||
|
||||
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
|
||||
|
||||
<ol>
|
||||
<li>Lorem ipsum dolor sit amet</li>
|
||||
<li>Lorem ipsum dolor sit amet</li>
|
||||
<li>Lorem ipsum dolor sit amet</li>
|
||||
<li>Lorem ipsum dolor sit amet</li>
|
||||
<li>Lorem ipsum dolor sit amet</li>
|
||||
</ol>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer id="publish-bar">
|
||||
<nav>
|
||||
<a id="entry-categories" href="#" class="left"><span class="icon-tag"></span> Category: Default</a>
|
||||
<div class="right">
|
||||
<a id="entry-settings" href="#" class="button-settings"><span class="icon-settings"></span> <span class="hidden">Settings</span></a>
|
||||
<a id="save-post" href="#" class="button button-save">Save Draft</a><a id="publish-post" href="#" class="button button-publish">Publish</a>
|
||||
</div>
|
||||
</nav>
|
||||
</footer>
|
||||
|
||||
</main>
|
||||
|
||||
<script type="text/javascript" src="assets/js/jquery.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
$(document).ready(function(){
|
||||
$('.entry-content header, .entry-preview header').click(function(){
|
||||
$('.entry-content, .entry-preview').removeClass('active');
|
||||
$(this).closest('section').addClass('active');
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|