Big front-end asset/filestructure refactor

- Extract shared Ember components into a “flarum-common” ember-cli
addon. This can be used by both the forum + admin Ember apps, keeping
things DRY
- Move LESS styles into their own top-level directory and do a similar
thing (extract common styles)
- Add LESS/JS compilation and versioning to PHP (AssetManager)
- Set up admin entry point

(Theoretical) upgrade instructions:
- Delete everything in [app_root]/public
- Set up tooling in forum/admin Ember apps (npm install/update, bower
install/update) and then build them (ember build)
- php artisan vendor:publish
- Upgrade flarum/flarum repo (slight change in a config file)
- If you need to trigger a LESS/JS recompile, delete the .css/.js files
in [app_root]/public/flarum. I set up LiveReload to do this for me when
I change files in less/ or ember/

Todo:
- Start writing admin app!
- Remove bootstrap/font-awesome from repo and instead depend on their
composer packages? Maybe? (Bower is not an option here)
This commit is contained in:
Toby Zerner 2015-03-29 22:13:26 +10:30
parent 10c1c4c09d
commit de10e4457f
286 changed files with 11344 additions and 460 deletions

View File

@ -12,7 +12,8 @@
"illuminate/support": "5.0.*",
"tobscure/json-api": "dev-master",
"tobscure/permissible": "dev-master",
"misd/linkify": "1.1.*"
"misd/linkify": "1.1.*",
"oyejorge/less.php": "dev-master"
},
"require-dev": {
"fzaninotto/faker": "1.4.0",

View File

@ -4,7 +4,7 @@
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "5b2f1014382942985a0fdf481770b8ce",
"hash": "f65be24ef3ec3cd5dd97390a0a76cd07",
"packages": [
{
"name": "danielstjules/stringy",
@ -135,12 +135,12 @@
"source": {
"type": "git",
"url": "https://github.com/illuminate/container.git",
"reference": "17cfa85970c5729cb504a7dfa0d142a5d1bb3547"
"reference": "a11c01c1d8b6941bd7ef2f104749ada5e34f146e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/container/zipball/17cfa85970c5729cb504a7dfa0d142a5d1bb3547",
"reference": "17cfa85970c5729cb504a7dfa0d142a5d1bb3547",
"url": "https://api.github.com/repos/illuminate/container/zipball/a11c01c1d8b6941bd7ef2f104749ada5e34f146e",
"reference": "a11c01c1d8b6941bd7ef2f104749ada5e34f146e",
"shasum": ""
},
"require": {
@ -170,7 +170,7 @@
],
"description": "The Illuminate Container package.",
"homepage": "http://laravel.com",
"time": "2015-03-07 15:07:05"
"time": "2015-03-25 17:06:14"
},
{
"name": "illuminate/contracts",
@ -278,12 +278,12 @@
"source": {
"type": "git",
"url": "https://github.com/illuminate/support.git",
"reference": "c29ac982d9710dc1b841f91be230b5eff57e5698"
"reference": "29e8618a45d090572e092abf193a257bf28c48d9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/support/zipball/c29ac982d9710dc1b841f91be230b5eff57e5698",
"reference": "c29ac982d9710dc1b841f91be230b5eff57e5698",
"url": "https://api.github.com/repos/illuminate/support/zipball/29e8618a45d090572e092abf193a257bf28c48d9",
"reference": "29e8618a45d090572e092abf193a257bf28c48d9",
"shasum": ""
},
"require": {
@ -322,7 +322,7 @@
],
"description": "The Illuminate Support package.",
"homepage": "http://laravel.com",
"time": "2015-03-25 16:42:17"
"time": "2015-03-27 14:49:11"
},
{
"name": "misd/linkify",
@ -422,6 +422,65 @@
],
"time": "2015-03-26 03:05:57"
},
{
"name": "oyejorge/less.php",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/oyejorge/less.php.git",
"reference": "c42eeffc7becaa92770730c34de6887a2063bd1c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/oyejorge/less.php/zipball/c42eeffc7becaa92770730c34de6887a2063bd1c",
"reference": "c42eeffc7becaa92770730c34de6887a2063bd1c",
"shasum": ""
},
"require": {
"php": ">=5.2"
},
"bin": [
"bin/lessc"
],
"type": "library",
"autoload": {
"psr-0": {
"Less": "lib/"
},
"classmap": [
"lessc.inc.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "Matt Agar",
"homepage": "https://github.com/agar"
},
{
"name": "Martin Jantošovič",
"homepage": "https://github.com/Mordred"
},
{
"name": "Josh Schmidt",
"homepage": "https://github.com/oyejorge"
}
],
"description": "PHP port of the Javascript version of LESS http://lesscss.org",
"homepage": "http://lessphp.gpeasy.com",
"keywords": [
"css",
"less",
"less.js",
"lesscss",
"php",
"stylesheet"
],
"time": "2015-03-23 16:12:13"
},
{
"name": "symfony/translation",
"version": "2.6.x-dev",
@ -562,12 +621,12 @@
"source": {
"type": "git",
"url": "https://github.com/Codeception/Codeception.git",
"reference": "7202e73252980bf881c3ba4f26b5bf9d70c02470"
"reference": "d3910b30105b9a0f8b2877c079c1fda8f3f6905c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/7202e73252980bf881c3ba4f26b5bf9d70c02470",
"reference": "7202e73252980bf881c3ba4f26b5bf9d70c02470",
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/d3910b30105b9a0f8b2877c079c1fda8f3f6905c",
"reference": "d3910b30105b9a0f8b2877c079c1fda8f3f6905c",
"shasum": ""
},
"require": {
@ -634,7 +693,7 @@
"functional testing",
"unit testing"
],
"time": "2015-03-26 10:33:44"
"time": "2015-03-28 23:22:32"
},
{
"name": "codeception/mockery-module",
@ -1189,12 +1248,12 @@
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
"reference": "07606749da971eda75434814a313ed0ce6790f6a"
"reference": "8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/07606749da971eda75434814a313ed0ce6790f6a",
"reference": "07606749da971eda75434814a313ed0ce6790f6a",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5",
"reference": "8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5",
"shasum": ""
},
"require": {
@ -1208,7 +1267,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.3.x-dev"
"dev-master": "1.4.x-dev"
}
},
"autoload": {
@ -1241,7 +1300,7 @@
"spy",
"stub"
],
"time": "2015-03-20 17:41:29"
"time": "2015-03-27 19:31:25"
},
{
"name": "phpunit/php-code-coverage",
@ -1493,12 +1552,12 @@
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "10f6685ca2cf5d8662b43a225ab853699821690b"
"reference": "14e06a4223608d1b9f434df3503b68945990bec6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/10f6685ca2cf5d8662b43a225ab853699821690b",
"reference": "10f6685ca2cf5d8662b43a225ab853699821690b",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/14e06a4223608d1b9f434df3503b68945990bec6",
"reference": "14e06a4223608d1b9f434df3503b68945990bec6",
"shasum": ""
},
"require": {
@ -1508,7 +1567,7 @@
"ext-reflection": "*",
"ext-spl": "*",
"php": ">=5.3.3",
"phpspec/prophecy": "~1.3.1",
"phpspec/prophecy": "~1.3,>=1.3.1",
"phpunit/php-code-coverage": "~2.0,>=2.0.11",
"phpunit/php-file-iterator": "~1.3.2",
"phpunit/php-text-template": "~1.2",
@ -1557,7 +1616,7 @@
"testing",
"xunit"
],
"time": "2015-03-02 06:58:30"
"time": "2015-03-28 20:45:33"
},
{
"name": "phpunit/phpunit-mock-objects",
@ -2415,7 +2474,8 @@
"minimum-stability": "dev",
"stability-flags": {
"tobscure/json-api": 20,
"tobscure/permissible": 20
"tobscure/permissible": 20,
"oyejorge/less.php": 20
},
"prefer-stable": false,
"prefer-lowest": false,

View File

@ -0,0 +1,4 @@
{
"directory": "bower_components",
"analytics": false
}

View File

@ -0,0 +1,33 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 2
[*.js]
indent_style = space
indent_size = 2
[*.hbs]
indent_style = space
indent_size = 2
[*.css]
indent_style = space
indent_size = 2
[*.html]
indent_style = space
indent_size = 2
[*.{diff,md}]
trim_trailing_whitespace = false

17
framework/core/ember/admin/.gitignore vendored Normal file
View File

@ -0,0 +1,17 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist
/tmp
# dependencies
/node_modules
/bower_components
# misc
/.sass-cache
/connect.lock
/coverage/*
/libpeerconnection.log
npm-debug.log
testem.log

View File

@ -0,0 +1,33 @@
{
"predef": [
"document",
"window",
"-Promise",
"moment"
],
"browser": true,
"boss": true,
"curly": true,
"debug": false,
"devel": true,
"eqeqeq": true,
"evil": true,
"forin": false,
"immed": false,
"laxbreak": false,
"newcap": true,
"noarg": true,
"noempty": false,
"nonew": false,
"nomen": false,
"onevar": false,
"plusplus": false,
"regexp": false,
"undef": true,
"sub": true,
"strict": false,
"white": false,
"eqnull": true,
"esnext": true,
"unused": true
}

View File

@ -0,0 +1,20 @@
---
language: node_js
sudo: false
cache:
directories:
- node_modules
before_install:
- "npm config set spin false"
- "npm install -g npm@^2"
install:
- npm install -g bower
- npm install
- bower install
script:
- npm test

View File

@ -0,0 +1,20 @@
/* global require, module */
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
var app = new EmberApp();
app.import('bower_components/bootstrap/dist/js/bootstrap.js');
app.import('bower_components/spin.js/spin.js');
app.import('bower_components/spin.js/jquery.spin.js');
app.import('bower_components/moment/moment.js');
app.import('bower_components/jquery.hotkeys/jquery.hotkeys.js');
app.import('bower_components/blurjs/dist/jquery.blur.js');
app.import('bower_components/font-awesome/fonts/fontawesome-webfont.eot');
app.import('bower_components/font-awesome/fonts/fontawesome-webfont.svg');
app.import('bower_components/font-awesome/fonts/fontawesome-webfont.ttf');
app.import('bower_components/font-awesome/fonts/fontawesome-webfont.woff');
app.import('bower_components/font-awesome/fonts/FontAwesome.otf');
module.exports = app.toTree();

View File

@ -0,0 +1,18 @@
import Ember from 'ember';
import Resolver from 'ember/resolver';
import loadInitializers from 'ember/load-initializers';
import config from './config/environment';
Ember.MODEL_FACTORY_INJECTIONS = true;
var App = Ember.Application.extend({
modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix,
Resolver: Resolver
});
loadInitializers(App, config.modulePrefix);
Ember.$('#assets-loading').remove();
export default App;

View File

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Flarum</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
{{content-for 'head'}}
<link rel="stylesheet" href="assets/vendor.css">
<link rel="stylesheet" href="assets/flarum.css">
{{content-for 'head-footer'}}
</head>
<body>
{{content-for 'body'}}
<script src="assets/vendor.js"></script>
<script src="assets/flarum.js"></script>
{{content-for 'body-footer'}}
</body>
</html>

View File

@ -0,0 +1,12 @@
import Ember from 'ember';
import config from './config/environment';
var Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
// this.resource('index', {path: '/'}
});
export default Router;

View File

@ -0,0 +1,7 @@
<div class="alerts">
{{#each alert in alerts}}
<div class="alert-wrapper">
{{view alert dismiss="dismissAlert"}}
</div>
{{/each}}
</div>

View File

@ -0,0 +1 @@
hey there

View File

@ -0,0 +1,13 @@
<header class="hero error-hero">
<div class="container">
<h2>Error</h2>
</div>
</header>
<div class="error-area">
<div class="container">
<p>{{model.message}}</p>
<pre>{{model.stack}}</pre>
</div>
</div>

View File

@ -0,0 +1 @@
{{ui/loading-indicator class="loading-indicator-block"}}

View File

@ -0,0 +1,28 @@
{
"name": "flarum-admin",
"dependencies": {
"jquery": "2.1.3",
"ember": "1.11.0-beta.3",
"ember-data": "1.0.0-beta.16.1",
"ember-resolver": "~0.1.11",
"loader.js": "ember-cli/loader.js#1.0.1",
"ember-cli-shims": "ember-cli/ember-cli-shims#0.0.3",
"ember-cli-test-loader": "0.1.3",
"ember-load-initializers": "ember-cli/ember-load-initializers#0.0.2",
"ember-qunit": "0.2.8",
"ember-qunit-notifications": "0.0.7",
"qunit": "~1.17.1",
"bootstrap": "~3.3.2",
"font-awesome": "~4",
"spin.js": "~2.0.1",
"moment": "~2.8.4",
"ember-simple-auth": "0.7.2",
"jquery.hotkeys": "jeresig/jquery.hotkeys#0.2.0",
"blurjs": ""
},
"resolutions": {
"ember-cli-test-loader": "0.1.3",
"ember-qunit": "0.2.8",
"ember-qunit-notifications": "0.0.7"
}
}

View File

@ -0,0 +1,53 @@
/* jshint node: true */
module.exports = function(environment) {
var ENV = {
modulePrefix: 'flarum-admin',
environment: environment,
baseURL: '/',
apiURL: '/api',
locationType: 'hash',
EmberENV: {
FEATURES: {
// Here you can enable experimental features on an ember canary build
// e.g. 'with-controller': true
}
},
APP: {
// Here you can pass flags/options to your application instance
// when it is created
}
};
ENV['simple-auth'] = {
authorizer: 'authorizer:flarum'
};
if (environment === 'development') {
// ENV.APP.LOG_RESOLVER = true;
// ENV.APP.LOG_ACTIVE_GENERATION = true;
// ENV.APP.LOG_TRANSITIONS = true;
// ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
// ENV.APP.LOG_VIEW_LOOKUPS = true;
}
if (environment === 'test') {
// Testem prefers this...
ENV.baseURL = '/';
ENV.locationType = 'none';
ENV.apiURL = 'http://flarum.dev/api',
// keep test console output quieter
ENV.APP.LOG_ACTIVE_GENERATION = false;
ENV.APP.LOG_VIEW_LOOKUPS = false;
ENV.APP.rootElement = '#ember-testing';
}
if (environment === 'production') {
}
return ENV;
};

View File

@ -0,0 +1,41 @@
{
"name": "flarum-admin",
"version": "0.0.0",
"private": true,
"directories": {
"doc": "doc",
"test": "tests"
},
"scripts": {
"start": "ember server",
"build": "ember build",
"test": "ember test"
},
"repository": "",
"engines": {
"node": ">= 0.10.0"
},
"author": "",
"license": "MIT",
"devDependencies": {
"ember-cli": "^0.2.0-beta.1",
"ember-cli-app-version": "0.3.1",
"ember-cli-babel": "^4.1.0",
"ember-cli-content-security-policy": "0.3.0",
"ember-cli-dependency-checker": "0.0.7",
"ember-cli-htmlbars": "^0.7.4",
"ember-cli-ic-ajax": "0.1.1",
"ember-cli-inject-live-reload": "^1.3.0",
"ember-cli-less": "^1.0.5",
"ember-cli-qunit": "^0.3.8",
"ember-cli-simple-auth": "^0.7.2",
"ember-cli-uglify": "1.0.1",
"ember-data": "1.0.0-beta.16.1",
"ember-export-application-global": "^1.0.2",
"ember-json-api": "eneuhauser/ember-json-api",
"broccoli-ember-inline-template-compiler": "tobscure/broccoli-ember-inline-template-compiler#f884d11",
"express": "^4.8.5",
"glob": "^4.0.5",
"flarum-common": "file:../common"
}
}

View File

@ -0,0 +1,11 @@
{
"framework": "qunit",
"test_page": "tests/index.html?hidepassed",
"launch_in_ci": [
"PhantomJS"
],
"launch_in_dev": [
"PhantomJS",
"Chrome"
]
}

View File

@ -0,0 +1,74 @@
{
"predef": [
"document",
"window",
"location",
"setTimeout",
"$",
"-Promise",
"QUnit",
"define",
"console",
"equal",
"notEqual",
"notStrictEqual",
"test",
"asyncTest",
"testBoth",
"testWithDefault",
"raises",
"throws",
"deepEqual",
"start",
"stop",
"ok",
"strictEqual",
"module",
"moduleFor",
"moduleForComponent",
"moduleForModel",
"process",
"expect",
"visit",
"exists",
"fillIn",
"click",
"keyEvent",
"triggerEvent",
"find",
"findWithAssert",
"wait",
"DS",
"isolatedContainer",
"startApp",
"andThen",
"currentURL",
"currentPath",
"currentRouteName"
],
"node": false,
"browser": false,
"boss": true,
"curly": false,
"debug": false,
"devel": false,
"eqeqeq": true,
"evil": true,
"forin": false,
"immed": false,
"laxbreak": false,
"newcap": true,
"noarg": true,
"noempty": false,
"nonew": false,
"nomen": false,
"onevar": false,
"plusplus": false,
"regexp": false,
"undef": true,
"sub": true,
"strict": false,
"white": false,
"eqnull": true,
"esnext": true
}

View File

@ -0,0 +1,11 @@
import Resolver from 'ember/resolver';
import config from '../../config/environment';
var resolver = Resolver.create();
resolver.namespace = {
modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix
};
export default resolver;

View File

@ -0,0 +1,19 @@
import Ember from 'ember';
import Application from '../../app';
import Router from '../../router';
import config from '../../config/environment';
export default function startApp(attrs) {
var application;
var attributes = Ember.merge({}, config.APP);
attributes = Ember.merge(attributes, attrs); // use defaults, but you can override;
Ember.run(function() {
application = Application.create(attributes);
application.setupForTesting();
application.injectTestHelpers();
});
return application;
}

View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Flarum Tests</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
{{content-for 'head'}}
{{content-for 'test-head'}}
<link rel="stylesheet" href="assets/vendor.css">
<link rel="stylesheet" href="assets/flarum.css">
<link rel="stylesheet" href="assets/test-support.css">
{{content-for 'head-footer'}}
{{content-for 'test-head-footer'}}
</head>
<body>
{{content-for 'body'}}
{{content-for 'test-body'}}
<script src="assets/vendor.js"></script>
<script src="assets/test-support.js"></script>
<script src="assets/flarum.js"></script>
<script src="testem.js"></script>
<script src="assets/test-loader.js"></script>
{{content-for 'body-footer'}}
{{content-for 'test-body-footer'}}
</body>
</html>

View File

@ -0,0 +1,48 @@
import Ember from "ember";
import { test } from 'ember-qunit';
import startApp from '../helpers/start-app';
var App;
module('Index', {
setup: function() {
App = startApp();
},
teardown: function() {
Ember.run(App, App.destroy);
}
});
test('Discussion list loading', function() {
expect(3);
visit('/').then(function() {
equal(find('.discussions-list').length, 1, 'Page contains list of discussions');
equal(find('.discussions-list li').length, 20, 'There are 20 discussions in the list');
click('.control-loadMore').then(function() {
equal(find('.discussions-list li').length, 40, 'There are 40 discussions in the list');
});
});
});
test('Discussion list sorting', function() {
expect(1);
visit('/').then(function() {
fillIn('.control-sort select', 'replies').then(function() {
var discussions = find('.discussions-list li');
var good = true;
var getCount = function(item) {
return parseInt(item.find('.count strong').text());
};
var previousCount = getCount(discussions.eq(0));
for (var i = 1; i < discussions.length; i++) {
var count = getCount(discussions.eq(i));
if (count > previousCount) {
good = false;
break;
}
previousCount = count;
}
ok(good, 'Discussions are listed in order of reply count');
});
});
});

View File

@ -0,0 +1,6 @@
import resolver from './helpers/resolver';
import {
setResolver
} from 'ember-qunit';
setResolver(resolver);

View File

@ -0,0 +1,4 @@
{
"directory": "bower_components",
"analytics": false
}

View File

@ -0,0 +1,33 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 2
[*.js]
indent_style = space
indent_size = 2
[*.hbs]
indent_style = space
indent_size = 2
[*.css]
indent_style = space
indent_size = 2
[*.html]
indent_style = space
indent_size = 2
[*.{diff,md}]
trim_trailing_whitespace = false

17
framework/core/ember/common/.gitignore vendored Normal file
View File

@ -0,0 +1,17 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist
/tmp
# dependencies
/node_modules
/bower_components
# misc
/.sass-cache
/connect.lock
/coverage/*
/libpeerconnection.log
npm-debug.log
testem.log

View File

@ -0,0 +1,32 @@
{
"predef": [
"document",
"window",
"-Promise"
],
"browser": true,
"boss": true,
"curly": true,
"debug": false,
"devel": true,
"eqeqeq": true,
"evil": true,
"forin": false,
"immed": false,
"laxbreak": false,
"newcap": true,
"noarg": true,
"noempty": false,
"nonew": false,
"nomen": false,
"onevar": false,
"plusplus": false,
"regexp": false,
"undef": true,
"sub": true,
"strict": false,
"white": false,
"eqnull": true,
"esnext": true,
"unused": true
}

View File

@ -0,0 +1,12 @@
bower_components/
tests/
.bowerrc
.editorconfig
.ember-cli
.travis.yml
.npmignore
**/.gitkeep
bower.json
Brocfile.js
testem.json

View File

@ -0,0 +1,20 @@
---
language: node_js
sudo: false
cache:
directories:
- node_modules
before_install:
- "npm config set spin false"
- "npm install -g npm@^2"
install:
- npm install -g bower
- npm install
- bower install
script:
- npm test

View File

@ -0,0 +1,21 @@
/* jshint node: true */
/* global require, module */
var EmberAddon = require('ember-cli/lib/broccoli/ember-addon');
var app = new EmberAddon();
// Use `app.import` to add additional libraries to the generated
// output files.
//
// If you need to use different assets in different
// environments, specify an object as the first parameter. That
// object's keys should be the environment name and the values
// should be the asset to use in that environment.
//
// If the library that you are including contains AMD or ES6
// modules that you would like to import into your application
// please specify an object with the list of modules as keys
// along with the exports of each module as its value.
module.exports = app.toTree();

View File

View File

@ -1,8 +1,8 @@
import DS from 'ember-data';
import JsonApiAdapter from 'ember-json-api/json-api-adapter';
import config from 'flarum/config/environment';
import AlertMessage from 'flarum/components/ui/alert-message';
import config from '../config/environment';
import AlertMessage from '../components/ui/alert-message';
export default JsonApiAdapter.extend({
host: config.apiURL,

View File

@ -1,7 +1,7 @@
import Ember from 'ember';
import HasItemLists from 'flarum/mixins/has-item-lists';
import ActionButton from 'flarum/components/ui/action-button';
import HasItemLists from '../../mixins/has-item-lists';
import ActionButton from './action-button';
/**
An alert message. Has a message, a `controls` item list, and a dismiss

View File

@ -1,4 +1,4 @@
import ActionButton from 'flarum/components/ui/action-button';
import ActionButton from './action-button';
export default ActionButton.extend({
tagName: 'span',

View File

@ -1,6 +1,6 @@
import Ember from 'ember';
import DropdownButton from 'flarum/components/ui/dropdown-button';
import DropdownButton from './dropdown-button';
/**
Given a list of items, this component displays a split button: the left side

View File

@ -1,7 +1,7 @@
import Ember from 'ember';
import HasItemLists from 'flarum/mixins/has-item-lists';
import ActionButton from 'flarum/components/ui/action-button';
import HasItemLists from '../../mixins/has-item-lists';
import ActionButton from './action-button';
/**
A text editor. Contains a textarea and an item list of `controls`, including

View File

@ -1,5 +1,5 @@
import FlarumAuthorizer from 'flarum/authorizers/flarum';
import Config from 'flarum/config/environment';
import FlarumAuthorizer from '../authorizers/flarum';
import Config from '../config/environment';
export default {
name: 'authentication',

View File

@ -0,0 +1,147 @@
import Ember from 'ember';
import humanTime from '../utils/human-time';
var $ = Ember.$;
export default {
name: 'human-time-updater',
initialize: function(container) {
// Livestamp.js / v1.1.2 / (c) 2012 Matt Bradley / MIT License
// @todo rewrite this to be simpler and cleaner
(function($, moment) {
var updateInterval = 1e3,
paused = false,
$livestamps = $([]),
init = function() {
livestampGlobal.resume();
},
prep = function($el, timestamp) {
var oldData = $el.data('livestampdata');
if (typeof timestamp == 'number')
timestamp *= 1e3;
$el.removeAttr('data-livestamp')
.removeData('livestamp');
timestamp = moment(timestamp);
if (timestamp.diff(moment(new Date())) < 60 * 60) {
return;
}
if (moment.isMoment(timestamp) && !isNaN(+timestamp)) {
var newData = $.extend({ }, { 'original': $el.contents() }, oldData);
newData.moment = moment(timestamp);
$el.data('livestampdata', newData).empty();
$livestamps.push($el[0]);
}
},
run = function() {
if (paused) return;
livestampGlobal.update();
setTimeout(run, updateInterval);
},
livestampGlobal = {
update: function() {
$('[data-humantime]').each(function() {
var $this = $(this);
prep($this, $this.attr('datetime'));
});
var toRemove = [];
$livestamps.each(function() {
var $this = $(this),
data = $this.data('livestampdata');
if (data === undefined)
toRemove.push(this);
else if (moment.isMoment(data.moment)) {
var from = $this.html(),
to = humanTime(data.moment);
// to = data.moment.fromNow();
if (from != to) {
var e = $.Event('change.livestamp');
$this.trigger(e, [from, to]);
if (!e.isDefaultPrevented())
$this.html(to);
}
}
});
$livestamps = $livestamps.not(toRemove);
},
pause: function() {
paused = true;
},
resume: function() {
paused = false;
run();
},
interval: function(interval) {
if (interval === undefined)
return updateInterval;
updateInterval = interval;
}
},
livestampLocal = {
add: function($el, timestamp) {
if (typeof timestamp == 'number')
timestamp *= 1e3;
timestamp = moment(timestamp);
if (moment.isMoment(timestamp) && !isNaN(+timestamp)) {
$el.each(function() {
prep($(this), timestamp);
});
livestampGlobal.update();
}
return $el;
},
destroy: function($el) {
$livestamps = $livestamps.not($el);
$el.each(function() {
var $this = $(this),
data = $this.data('livestampdata');
if (data === undefined)
return $el;
$this
.html(data.original ? data.original : '')
.removeData('livestampdata');
});
return $el;
},
isLivestamp: function($el) {
return $el.data('livestampdata') !== undefined;
}
};
$.livestamp = livestampGlobal;
$(init);
$.fn.livestamp = function(method, options) {
if (!livestampLocal[method]) {
options = method;
method = 'add';
}
return livestampLocal[method](this, options);
};
})(jQuery, moment);
}
};

View File

@ -1,8 +1,8 @@
import Ember from 'ember';
import TaggedArray from 'flarum/utils/tagged-array';
import ActionButton from 'flarum/components/ui/action-button';
import SeparatorItem from 'flarum/components/ui/separator-item';
import TaggedArray from '../utils/tagged-array';
import ActionButton from '../components/ui/action-button';
import SeparatorItem from '../components/ui/separator-item';
export default Ember.Mixin.create({
itemLists: [],

View File

@ -1,7 +1,7 @@
import Ember from 'ember';
import DS from 'ember-data';
import HasItemLists from 'flarum/mixins/has-item-lists';
import HasItemLists from '../mixins/has-item-lists';
import Subject from './subject';
export default Subject.extend(HasItemLists, {

View File

@ -1,7 +1,7 @@
import DS from 'ember-data';
import HasItemLists from 'flarum/mixins/has-item-lists';
import stringToColor from 'flarum/utils/string-to-color';
import HasItemLists from '../mixins/has-item-lists';
import stringToColor from '../utils/string-to-color';
export default DS.Model.extend(HasItemLists, {
itemLists: ['badges'],

View File

@ -1,4 +1,4 @@
import ApplicationSerializer from 'flarum/serializers/application';
import ApplicationSerializer from '../serializers/application';
export default ApplicationSerializer.extend({
attrs: {

Some files were not shown because too many files have changed in this diff Show More