├── .gitattributes ├── .gitignore ├── LICENSE ├── Procfile ├── README.md ├── app ├── __init__.py ├── admin │ ├── __init__.py │ ├── forms.py │ └── views.py ├── auth │ ├── __init__.py │ ├── forms.py │ └── views.py ├── main │ ├── __init__.py │ ├── errors.py │ ├── forms.py │ └── views.py ├── models.py ├── static │ ├── css │ │ ├── bootstrap-theme.css │ │ ├── bootstrap-theme.css.map │ │ ├── bootstrap-theme.min.css │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ ├── bootstrap.min.css │ │ ├── common.css │ │ └── prism.css │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ ├── images │ │ └── background.jpg │ ├── js │ │ ├── admin.js │ │ ├── bootstrap.js │ │ ├── bootstrap.min.js │ │ ├── commentReply.js │ │ ├── floatButton.js │ │ ├── jquery-1.12.0.min.js │ │ ├── jquery-1.8.3.min.js │ │ ├── jquery-2.1.4.min.js │ │ ├── jquery-2.2.1.min.js │ │ ├── npm.js │ │ └── tinymce_setup.js │ └── tinymce │ │ ├── LICENSE.TXT │ │ ├── changelog.txt │ │ └── js │ │ └── tinymce │ │ ├── extentsion_self │ │ └── codesimple_extentsion │ │ │ └── prism.js │ │ ├── jquery.tinymce.min.js │ │ ├── langs │ │ ├── readme.md │ │ └── zh_CN.js │ │ ├── license.txt │ │ ├── plugins │ │ ├── advlist │ │ │ └── plugin.min.js │ │ ├── anchor │ │ │ └── plugin.min.js │ │ ├── autolink │ │ │ └── plugin.min.js │ │ ├── autoresize │ │ │ └── plugin.min.js │ │ ├── autosave │ │ │ └── plugin.min.js │ │ ├── bbcode │ │ │ └── plugin.min.js │ │ ├── charmap │ │ │ └── plugin.min.js │ │ ├── code │ │ │ └── plugin.min.js │ │ ├── codesample │ │ │ ├── css │ │ │ │ └── prism.css │ │ │ └── plugin.min.js │ │ ├── colorpicker │ │ │ └── plugin.min.js │ │ ├── contextmenu │ │ │ └── plugin.min.js │ │ ├── directionality │ │ │ └── plugin.min.js │ │ ├── emoticons │ │ │ ├── img │ │ │ │ ├── smiley-cool.gif │ │ │ │ ├── smiley-cry.gif │ │ │ │ ├── smiley-embarassed.gif │ │ │ │ ├── smiley-foot-in-mouth.gif │ │ │ │ ├── smiley-frown.gif │ │ │ │ ├── smiley-innocent.gif │ │ │ │ ├── smiley-kiss.gif │ │ │ │ ├── smiley-laughing.gif │ │ │ │ ├── smiley-money-mouth.gif │ │ │ │ ├── smiley-sealed.gif │ │ │ │ ├── smiley-smile.gif │ │ │ │ ├── smiley-surprised.gif │ │ │ │ ├── smiley-tongue-out.gif │ │ │ │ ├── smiley-undecided.gif │ │ │ │ ├── smiley-wink.gif │ │ │ │ └── smiley-yell.gif │ │ │ └── plugin.min.js │ │ ├── example │ │ │ ├── dialog.html │ │ │ └── plugin.min.js │ │ ├── example_dependency │ │ │ └── plugin.min.js │ │ ├── fullpage │ │ │ └── plugin.min.js │ │ ├── fullscreen │ │ │ └── plugin.min.js │ │ ├── hr │ │ │ └── plugin.min.js │ │ ├── image │ │ │ └── plugin.min.js │ │ ├── imagetools │ │ │ └── plugin.min.js │ │ ├── importcss │ │ │ └── plugin.min.js │ │ ├── insertdatetime │ │ │ └── plugin.min.js │ │ ├── layer │ │ │ └── plugin.min.js │ │ ├── legacyoutput │ │ │ └── plugin.min.js │ │ ├── link │ │ │ └── plugin.min.js │ │ ├── lists │ │ │ └── plugin.min.js │ │ ├── media │ │ │ ├── moxieplayer.swf │ │ │ └── plugin.min.js │ │ ├── nonbreaking │ │ │ └── plugin.min.js │ │ ├── noneditable │ │ │ └── plugin.min.js │ │ ├── pagebreak │ │ │ └── plugin.min.js │ │ ├── paste │ │ │ └── plugin.min.js │ │ ├── preview │ │ │ └── plugin.min.js │ │ ├── print │ │ │ └── plugin.min.js │ │ ├── save │ │ │ └── plugin.min.js │ │ ├── searchreplace │ │ │ └── plugin.min.js │ │ ├── spellchecker │ │ │ └── plugin.min.js │ │ ├── tabfocus │ │ │ └── plugin.min.js │ │ ├── table │ │ │ └── plugin.min.js │ │ ├── template │ │ │ └── plugin.min.js │ │ ├── textcolor │ │ │ └── plugin.min.js │ │ ├── textpattern │ │ │ └── plugin.min.js │ │ ├── visualblocks │ │ │ ├── css │ │ │ │ └── visualblocks.css │ │ │ └── plugin.min.js │ │ ├── visualchars │ │ │ └── plugin.min.js │ │ └── wordcount │ │ │ └── plugin.min.js │ │ ├── skins │ │ ├── lightgray │ │ │ ├── content.inline.min.css │ │ │ ├── content.min.css │ │ │ ├── fonts │ │ │ │ ├── tinymce-small.eot │ │ │ │ ├── tinymce-small.svg │ │ │ │ ├── tinymce-small.ttf │ │ │ │ ├── tinymce-small.woff │ │ │ │ ├── tinymce.eot │ │ │ │ ├── tinymce.svg │ │ │ │ ├── tinymce.ttf │ │ │ │ └── tinymce.woff │ │ │ ├── img │ │ │ │ ├── anchor.gif │ │ │ │ ├── loader.gif │ │ │ │ ├── object.gif │ │ │ │ └── trans.gif │ │ │ ├── skin.ie7.min.css │ │ │ └── skin.min.css │ │ └── myskin │ │ │ ├── Variables.less │ │ │ ├── content.inline.min.css │ │ │ ├── content.min.css │ │ │ ├── fonts │ │ │ ├── readme.md │ │ │ ├── tinymce-small.eot │ │ │ ├── tinymce-small.json │ │ │ ├── tinymce-small.svg │ │ │ ├── tinymce-small.ttf │ │ │ ├── tinymce-small.woff │ │ │ ├── tinymce.eot │ │ │ ├── tinymce.json │ │ │ ├── tinymce.svg │ │ │ ├── tinymce.ttf │ │ │ └── tinymce.woff │ │ │ ├── img │ │ │ ├── anchor.gif │ │ │ ├── loader.gif │ │ │ ├── object.gif │ │ │ └── trans.gif │ │ │ ├── skin.ie7.min.css │ │ │ ├── skin.json │ │ │ └── skin.min.css │ │ ├── themes │ │ └── modern │ │ │ └── theme.min.js │ │ └── tinymce.min.js └── templates │ ├── 403.html │ ├── 404.html │ ├── 500.html │ ├── _article_comments.html │ ├── _article_entry.html │ ├── _article_info.html │ ├── _macros.html │ ├── _submit_comment.html │ ├── admin │ ├── admin_account.html │ ├── admin_base.html │ ├── blog_plugin_add.html │ ├── custom_blog_info.html │ ├── custom_blog_plugin.html │ ├── help_page.html │ ├── manage_articleTypes.html │ ├── manage_articleTypes_nav.html │ ├── manage_articles.html │ ├── manage_comments.html │ └── submit_articles.html │ ├── article_detials.html │ ├── auth │ └── login.html │ ├── base.html │ └── index.html ├── config.py ├── manage.py ├── migrations ├── README ├── alembic.ini ├── env.py ├── script.py.mako └── versions │ └── 051691f120e6_fit_to_mysql.py ├── requirements.txt └── requirements ├── common.txt └── dev.txt /.gitattributes: -------------------------------------------------------------------------------- 1 | *.html linguist-language=python 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | *.pyc 3 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: gunicorn manage:app 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 2018-07-06说明 2 | 3 | 之前的服务器地址140.143.205.19已经不可用,现已经更改为如下地址: 4 | 5 | ``` 6 | 试用地址:http://122.152.231.228:8080/ 7 | 帐号:blog_mini@163.com 8 | 密码:blog_mini 9 | ``` 10 | 11 | Blog_mini的Demo网站停了近一个月,由于6月份,几乎整个月的时间都忙于毕业的事情,也没有时间去处理,后段时间由于又给自己放了一个小假期,所以是迟迟未能解决问题,给部分想参考Demo的朋友带来不便,实在是非常抱歉! 12 | 13 | 现已经购买了一年的服务器时长,所以服务会一直运行下去,感谢大家的关注和支持! 14 | 15 | ### 2018-02-09说明 16 | 17 | 之前的服务器地址115.159.72.250已经不可用,现已经更改为如下地址: 18 | 19 | ```shell 20 | 试用地址:140.143.205.19 21 | 帐号:blog_mini@163.com 22 | 密码:blog_mini 23 | ``` 24 | 25 | 承蒙大家喜爱,Blog_mini已经走过两年的时间了,从`star`和`fork`来看,很开心很高兴很多网友朋友能够把它作为自己入门Python和Python Web的一个小项目来进行学习,也正因为如此,一种不可言喻的责任就背负在身上,我总是担心这个小项目中可能出现的不可预知的坑会给部分初学的朋友带来很大的困难。大概从2017年开始,我就有意要整体改进和完善Blog_mini这个小项目。 26 | 27 | 然而过去两年作为大学阶段十分重要的两年,确实有太多的事情,因此这个计划一直耽误至今。眼看马上临近毕业,毕业设计也需要花费一定的时间和精力,所以还会继续耽误一小段时间。但不管如何,今年一定会努力争取完成这件事情。 28 | 29 | 计划将会从界面UI、后台管理系统、开发文档、代码注释等方面对这个小项目进行完善,这样之后,真心希望初学者都能够通过这样一个小项目来加强对Python基础技能以及其它技能的学习,达到可以使用Python进行基本开发这样的一种状态,去体验Python给自己带来的快乐。 30 | 31 | --- 32 | 33 | # Blog_mini 34 | 35 | ### 1.功能强大的开源博客系统 36 | Blog_mini是一个开源的博客系统,用Python开发完成,具有简洁的界面和强大的后台管理, 37 | 38 | 使用它,你可以轻松架设属于您自己的个人博客网站! 39 | 40 | 只要把Blog_mini部署上,您不需要再进行任何命令上的操作即可以轻松使用和管理您的个人博客! 41 | 42 | ### 2.完整而详尽的部署文档 43 | 我们撰写了非常详细的部署文档,涵盖了CentOS和Ubuntu,可见下面地址: 44 | 45 | Blog_mini详细部署文档:http://xpleaf.blog.51cto.com/blog/9315560/1748871 46 | 47 | 作者亲测,在网络环境良好的情况下,最快用3分钟即可以把Blog_mini部署并上线! 48 | 49 | ### 3.提供试用地址 50 | 如果你只是想试用Blog_mini的功能,我们提供了试用地址: 51 | 52 | 试用地址:115.159.72.250:8080 53 | 帐号:blog_mini@163.com 54 | 密码:blog_mini 55 | 56 | 已经有很多网友对Blog_mini进行了体验,我们欢迎您使用,并且能就使用过程中的一些问题给予作者意见和建议。 57 | 58 | ### 4.值得一学的源代码 59 | 如果你初学Python Web,或者你从来没有进行过一个完整项目的开发,或者你以后想从事Python自动化运维开发的工作, 60 | 61 | 不妨阅读并学习一下Blog_mini的源代码。 62 | 63 | Blog_mini采用结构清晰的工厂模式来设计开发,其中的一些开发思想模仿了国外牛人miguelgrinberg,因此,值得一学! 64 | 65 | ### 5.技术支持 66 | 如果你在部署和使用过程中有疑问,请给作者留言: 67 | 68 | 作者51cto博客:http://xpleaf.blog.51cto.com 69 | 作者个人博客网站:http://www.xpleaf.cn(目前不可访问) 70 | 郑重说明:http://www.xpleaf.com这个域名已经被抢注,并且被用于发布不良内容,我将会进行举报! 71 | 72 | -------------------------------------------------------------------------------- /app/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from flask.ext.sqlalchemy import SQLAlchemy 3 | from flask.ext.bootstrap import Bootstrap 4 | from flask.ext.login import LoginManager 5 | from flask_wtf.csrf import CsrfProtect 6 | from flask_moment import Moment 7 | from config import Config 8 | 9 | 10 | db = SQLAlchemy() 11 | bootstrap = Bootstrap() 12 | moment = Moment() 13 | login_manager = LoginManager() 14 | login_manager.session_protection = 'strong' 15 | login_manager.login_view = 'auth.login' 16 | 17 | 18 | def create_app(): 19 | app = Flask(__name__) 20 | app.config.from_object(Config) 21 | Config.init_app(app) 22 | CsrfProtect(app) 23 | 24 | db.init_app(app) 25 | bootstrap.init_app(app) 26 | moment.init_app(app) 27 | login_manager.init_app(app) 28 | 29 | from .main import main as main_blueprint 30 | app.register_blueprint(main_blueprint) 31 | 32 | from .admin import admin as admin_blueprint 33 | app.register_blueprint(admin_blueprint, url_prefix='/admin') 34 | 35 | from .auth import auth as auth_blueprint 36 | app.register_blueprint(auth_blueprint, url_prefix='/auth') 37 | 38 | return app 39 | -------------------------------------------------------------------------------- /app/admin/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Blueprint 2 | 3 | 4 | admin = Blueprint('admin', __name__) 5 | 6 | 7 | from . import views -------------------------------------------------------------------------------- /app/admin/forms.py: -------------------------------------------------------------------------------- 1 | # coding:utf-8 2 | from flask.ext.wtf import Form 3 | from wtforms import SelectField, StringField, TextAreaField, SubmitField, \ 4 | PasswordField 5 | from wtforms.validators import DataRequired, Length, Email, EqualTo 6 | from ..main.forms import CommentForm 7 | 8 | 9 | class CommonForm(Form): 10 | types = SelectField(u'博文分类', coerce=int, validators=[DataRequired()]) 11 | source = SelectField(u'博文来源', coerce=int, validators=[DataRequired()]) 12 | 13 | 14 | class SubmitArticlesForm(CommonForm): 15 | title = StringField(u'标题', validators=[DataRequired(), Length(1, 64)]) 16 | content = TextAreaField(u'博文内容', validators=[DataRequired()]) 17 | summary = TextAreaField(u'博文摘要', validators=[DataRequired()]) 18 | 19 | 20 | class ManageArticlesForm(CommonForm): 21 | pass 22 | 23 | 24 | class DeleteArticleForm(Form): 25 | articleId = StringField(validators=[DataRequired()]) 26 | 27 | 28 | class DeleteArticlesForm(Form): 29 | articleIds = StringField(validators=[DataRequired()]) 30 | 31 | 32 | class DeleteCommentsForm(Form): 33 | commentIds = StringField(validators=[DataRequired()]) 34 | 35 | 36 | class AdminCommentForm(CommentForm): 37 | article = StringField(validators=[DataRequired()]) 38 | 39 | 40 | class AddArticleTypeForm(Form): 41 | name = StringField(u'分类名称', validators=[DataRequired(), Length(1, 64)]) 42 | introduction = TextAreaField(u'分类介绍') 43 | setting_hide = SelectField(u'属性', coerce=int, validators=[DataRequired()]) 44 | menus = SelectField(u'所属导航', coerce=int, validators=[DataRequired()]) 45 | # You must add coerce=int, or the SelectFile validate function only validate the int data 46 | 47 | 48 | class EditArticleTypeForm(AddArticleTypeForm): 49 | articleType_id = StringField(validators=[DataRequired()]) 50 | 51 | 52 | class AddArticleTypeNavForm(Form): 53 | name = StringField(u'导航名称', validators=[DataRequired(), Length(1, 64)]) 54 | 55 | 56 | class EditArticleNavTypeForm(AddArticleTypeNavForm): 57 | nav_id = StringField(validators=[DataRequired()]) 58 | 59 | 60 | class SortArticleNavTypeForm(AddArticleTypeNavForm): 61 | order = StringField(u'序号', validators=[DataRequired()]) 62 | 63 | 64 | class CustomBlogInfoForm(Form): 65 | title = StringField(u'博客标题', validators=[DataRequired()]) 66 | signature = TextAreaField(u'个性签名', validators=[DataRequired()]) 67 | navbar = SelectField(u'导航样式', coerce=int, validators=[DataRequired()]) 68 | 69 | 70 | class AddBlogPluginForm(Form): 71 | title = StringField(u'插件名称', validators=[DataRequired()]) 72 | note = TextAreaField(u'备注') 73 | content = TextAreaField(u'内容', validators=[DataRequired()]) 74 | 75 | 76 | class ChangePasswordForm(Form): 77 | old_password = PasswordField(u'原来密码', validators=[DataRequired()]) 78 | password = PasswordField(u'新密码', validators=[ 79 | DataRequired(), EqualTo('password2', message=u'两次输入密码不一致!')]) 80 | password2 = PasswordField(u'确认新密码', validators=[DataRequired()]) 81 | 82 | 83 | class EditUserInfoForm(Form): 84 | username = StringField(u'昵称', validators=[DataRequired()]) 85 | email = StringField(u'电子邮件', validators=[DataRequired(), Length(1, 64), Email()]) 86 | password = PasswordField(u'密码确认', validators=[DataRequired()]) 87 | -------------------------------------------------------------------------------- /app/auth/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Blueprint 2 | 3 | auth = Blueprint('auth', __name__) 4 | 5 | from . import views 6 | -------------------------------------------------------------------------------- /app/auth/forms.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from flask_wtf import Form 3 | from wtforms import StringField, PasswordField, SubmitField 4 | from wtforms.validators import DataRequired, Length, Email 5 | 6 | 7 | class LoginForm(Form): 8 | email = StringField(u'电子邮件', validators=[DataRequired(), Length(1, 64), 9 | Email()]) 10 | password = PasswordField(u'密码', validators=[DataRequired()]) 11 | -------------------------------------------------------------------------------- /app/auth/views.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | from flask import render_template, redirect, request, url_for, flash 3 | from flask.ext.login import login_user, login_required, logout_user 4 | from . import auth 5 | from ..models import User 6 | from .forms import LoginForm 7 | 8 | 9 | @auth.route('/login', methods=['GET', 'POST']) 10 | def login(): 11 | form = LoginForm() 12 | if form.validate_on_submit(): 13 | user = User.query.filter_by(email=form.email.data).first() 14 | if user is not None and user.verify_password(form.password.data): 15 | login_user(user) 16 | flash(u'登陆成功!欢迎回来,%s!' % user.username, 'success') 17 | return redirect(request.args.get('next') or url_for('main.index')) 18 | else: 19 | flash(u'登陆失败!用户名或密码错误,请重新登陆。', 'danger') 20 | if form.errors: 21 | flash(u'登陆失败,请尝试重新登陆.', 'danger') 22 | 23 | return render_template('auth/login.html', form=form) 24 | 25 | 26 | @auth.route('/logout') 27 | @login_required 28 | def logout(): 29 | logout_user() 30 | flash(u'您已退出登陆。', 'success') 31 | return redirect(url_for('main.index')) 32 | -------------------------------------------------------------------------------- /app/main/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Blueprint 2 | 3 | main = Blueprint('main', __name__) 4 | 5 | from . import views, errors -------------------------------------------------------------------------------- /app/main/errors.py: -------------------------------------------------------------------------------- 1 | from flask import render_template, request, jsonify 2 | from . import main 3 | 4 | 5 | @main.app_errorhandler(403) 6 | def forbidden(e): 7 | 8 | return render_template('403.html'), 403 9 | 10 | 11 | @main.app_errorhandler(404) 12 | def page_not_found(e): 13 | 14 | return render_template('404.html'), 404 15 | 16 | 17 | @main.app_errorhandler(500) 18 | def internal_server_error(e): 19 | 20 | return render_template('500.html'), 500 21 | -------------------------------------------------------------------------------- /app/main/forms.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | from flask.ext.wtf import Form 3 | from wtforms import StringField, SubmitField, TextAreaField 4 | from wtforms.validators import DataRequired, Length, Email, Optional 5 | 6 | 7 | class CommentForm(Form): 8 | name = StringField(u'昵称', validators=[DataRequired()]) 9 | email = StringField(u'邮箱', validators=[DataRequired(), Length(1, 64), 10 | Email()]) 11 | content = TextAreaField(u'内容', validators=[DataRequired(), Length(1, 1024)]) 12 | follow = StringField(validators=[DataRequired()]) 13 | -------------------------------------------------------------------------------- /app/main/views.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | from flask import render_template, request, current_app, redirect,\ 3 | url_for, flash 4 | from . import main 5 | from ..models import Article, ArticleType, article_types, Comment, \ 6 | Follow, User, Source, BlogView 7 | from .forms import CommentForm 8 | from .. import db 9 | 10 | 11 | @main.route('/') 12 | def index(): 13 | BlogView.add_view(db) 14 | page = request.args.get('page', 1, type=int) 15 | pagination = Article.query.order_by(Article.create_time.desc()).paginate( 16 | page, per_page=current_app.config['ARTICLES_PER_PAGE'], 17 | error_out=False) 18 | articles = pagination.items 19 | return render_template('index.html', articles=articles, 20 | pagination=pagination, endpoint='.index') 21 | 22 | 23 | @main.route('/article-types//') 24 | def articleTypes(id): 25 | BlogView.add_view(db) 26 | page = request.args.get('page', 1, type=int) 27 | pagination = ArticleType.query.get_or_404(id).articles.order_by( 28 | Article.create_time.desc()).paginate( 29 | page, per_page=current_app.config['ARTICLES_PER_PAGE'], 30 | error_out=False) 31 | articles = pagination.items 32 | return render_template('index.html', articles=articles, 33 | pagination=pagination, endpoint='.articleTypes', 34 | id=id) 35 | 36 | 37 | @main.route('/article-sources//') 38 | def article_sources(id): 39 | BlogView.add_view(db) 40 | page = request.args.get('page', 1, type=int) 41 | pagination = Source.query.get_or_404(id).articles.order_by( 42 | Article.create_time.desc()).paginate( 43 | page, per_page=current_app.config['ARTICLES_PER_PAGE'], 44 | error_out=False) 45 | articles = pagination.items 46 | return render_template('index.html', articles=articles, 47 | pagination=pagination, endpoint='.article_sources', 48 | id=id) 49 | 50 | 51 | @main.route('/article-detials/', methods=['GET', 'POST']) 52 | def articleDetails(id): 53 | BlogView.add_view(db) 54 | form = CommentForm(request.form, follow=-1) 55 | article = Article.query.get_or_404(id) 56 | 57 | if form.validate_on_submit(): 58 | comment = Comment(article=article, 59 | content=form.content.data, 60 | author_name=form.name.data, 61 | author_email=form.email.data) 62 | db.session.add(comment) 63 | db.session.commit() 64 | followed_id = int(form.follow.data) 65 | if followed_id != -1: 66 | followed = Comment.query.get_or_404(followed_id) 67 | f = Follow(follower=comment, followed=followed) 68 | comment.comment_type = 'reply' 69 | comment.reply_to = followed.author_name 70 | db.session.add(f) 71 | db.session.add(comment) 72 | db.session.commit() 73 | flash(u'提交评论成功!', 'success') 74 | return redirect(url_for('.articleDetails', id=article.id, page=-1)) 75 | if form.errors: 76 | flash(u'发表评论失败', 'danger') 77 | 78 | page = request.args.get('page', 1, type=int) 79 | if page == -1: 80 | page = (article.comments.count() - 1) // \ 81 | current_app.config['COMMENTS_PER_PAGE'] + 1 82 | pagination = article.comments.order_by(Comment.timestamp.asc()).paginate( 83 | page, per_page=current_app.config['COMMENTS_PER_PAGE'], 84 | error_out=False) 85 | comments = pagination.items 86 | article.add_view(article, db) 87 | return render_template('article_detials.html', User=User, article=article, 88 | comments=comments, pagination=pagination, page=page, 89 | form=form, endpoint='.articleDetails', id=article.id) 90 | # page=page, this is used to return the current page args to the 91 | # disable comment or enable comment endpoint to pass it to the articleDetails endpoint 92 | -------------------------------------------------------------------------------- /app/static/css/common.css: -------------------------------------------------------------------------------- 1 | /*CSS For common appearance*/ 2 | body { 3 | /*background: #F0F0F0;*/ 4 | background: url('../images/background.jpg'); 5 | } 6 | .blog-title a:link { 7 | text-decoration: none; 8 | } 9 | .signature { 10 | padding-left: 0px; 11 | } 12 | .content { 13 | min-height: 800px; 14 | } 15 | .article-entry-sum { 16 | margin-top: 5px; 17 | } 18 | .entry-box { 19 | background: #fff; 20 | padding: 15px; 21 | margin-bottom: 20px; 22 | border: 1px solid #e6e6e6; 23 | border-radius: 4px; 24 | } 25 | .entry-box:hover { 26 | box-shadow: 2px 2px 8px rgba(0,0,0,.2); 27 | border-color: #d6d6d6; 28 | } 29 | .article-entry-header { 30 | margin: 0; 31 | padding: 0; 32 | border: 0; 33 | font: inherit; 34 | vertical-align: baseline; 35 | } 36 | .article-entry-title { 37 | text-align: center; 38 | margin-bottom: 10px; 39 | } 40 | .article-entry-title a { 41 | text-decoration: none; 42 | } 43 | .article-entry-info { 44 | height: 35px; 45 | } 46 | .article-entry-info .base-info { 47 | float: left; 48 | } 49 | .article-entry-info .main-info { 50 | float: right; 51 | } 52 | .footer { 53 | background: #474E5D; 54 | padding: 15px 0 5px; 55 | font-size: 13px; 56 | } 57 | .footer-content { 58 | text-align: center; 59 | color: #8a6d3b; 60 | } 61 | div.pagination { 62 | width: 100%; 63 | text-align: center; 64 | padding: 0px; 65 | margin: 0px; 66 | } 67 | .footer-content a { 68 | text-decoration: none; 69 | } 70 | 71 | /*CSS For Comments(Article details page)*/ 72 | ul.comments { 73 | list-style-type: none; 74 | padding: 0px; 75 | margin: 16px 0px 0px 0px; 76 | } 77 | ul.comments li.comment:nth-child(1) { 78 | border-top: 1px solid #e0e0e0; 79 | } 80 | ul.comments li.comment { 81 | margin-left: 32px; 82 | padding: 8px; 83 | border-bottom: 1px solid #e0e0e0; 84 | } 85 | div.comment-thumbnail { 86 | position: absolute; 87 | } 88 | .profile-thumbnail { 89 | position: absolute; 90 | } 91 | ul.comments div.comment-info { 92 | margin-left: 48px; 93 | min-height: 48px; 94 | } 95 | ul.comments li.comment:hover { 96 | background-color: #f0f0f0; 97 | } 98 | ul.comments .comment-date { 99 | float: right; 100 | color: #8c8c8c; 101 | } 102 | ul.comments .comment-author { 103 | font-weight: bold; 104 | color: #337ab7; 105 | } 106 | ul.comments .delete-comment{ 107 | margin: 0px 5px 0px 5px; 108 | } 109 | .comment-reply-info { 110 | color: #3f42cd; 111 | } 112 | 113 | /*CSS For Comments(admin page), use the same CSS as above*/ 114 | ul.comments .comment-handle-admin { 115 | float: right; 116 | } 117 | ul.comments .disabled-comment-admin-info { 118 | color: #2c4a35; 119 | } 120 | ul.comments div.comment-info-admin { 121 | margin-left: 68px; 122 | min-height: 48px; 123 | } 124 | div.manage-comments .select-comments-admin { 125 | margin-left: 40px; 126 | } 127 | div.manage-comments .handle-box-admin { 128 | margin-bottom: -10px; 129 | } 130 | div.manage-comments .delComments { 131 | float: right; 132 | } 133 | ul.comments .delete-comment-admin-btn { 134 | margin-left: 5px; 135 | margin-right: 5px; 136 | } 137 | ul.comments .disabled-comment-admin-btn { 138 | margin-left: 5px; 139 | } 140 | 141 | /*CSS For submit comment*/ 142 | .comment-submit { 143 | margin-left: 25px; 144 | } 145 | 146 | /*CSS For floatButton*/ 147 | .floatButton { 148 | position: fixed; 149 | top: 50%; 150 | right: 0; 151 | z-index: 9999999; 152 | } 153 | 154 | /*CSS For submit article*/ 155 | .submit-article-title { 156 | width: 450px; 157 | } 158 | .submit-article-editor { 159 | margin: 10px 0px 10px 0px; 160 | } 161 | .submit-article-summary { 162 | width: 500px; 163 | } 164 | .submit-article-button { 165 | text-align: center; 166 | } 167 | /*.submit-article-button {*/ 168 | /*margin: auto;*/ 169 | /*}*/ 170 | 171 | /*CSS For edit article*/ 172 | .article-edit { 173 | text-align: right; 174 | } 175 | 176 | /*CSS For manage articles*/ 177 | .articles-list { 178 | margin-left: 30px; 179 | margin-right: 30px; 180 | } 181 | .manage-articles th { 182 | text-align: center; 183 | } 184 | .manage-articles td { 185 | text-align: center; 186 | } 187 | .manage-articles .table-header { 188 | background-color: #779ecb 189 | } 190 | .manage-articles .table-checkbox-or-left { 191 | text-align: left; 192 | } 193 | .manage-articles .delete-article { 194 | color: #c9302c; 195 | } 196 | .manage-articles .list-handle { 197 | padding-bottom: 25px; 198 | } 199 | 200 | /*CSS For manage articleTypes*/ 201 | .manage-articleTypes .articleTypes-box { 202 | margin-left: 30px; 203 | margin-right: 30px; 204 | } 205 | .manage-articleTypes th { 206 | text-align: center; 207 | } 208 | .manage-articleTypes td { 209 | text-align: center; 210 | } 211 | .manage-articleTypes .table-header { 212 | background-color: #779ecb; 213 | /*background-color: #337ab7;*/ 214 | } 215 | .manage-articleTypes .table-checkbox-or-left { 216 | text-align: left; 217 | } 218 | .manage-articleTypes .delete-articleType { 219 | color: #c9302c; 220 | } 221 | .manage-articleTypes .add-articleType-btn { 222 | float: right; 223 | } 224 | 225 | /*CSS For manage articleTypes nav*/ 226 | .manage-articleTypes-nav .articleTypes-nav-box { 227 | margin-left: 30px; 228 | margin-right: 30px; 229 | } 230 | .manage-articleTypes-nav th { 231 | text-align: center; 232 | } 233 | .manage-articleTypes-nav td { 234 | text-align: center; 235 | } 236 | .manage-articleTypes-nav .table-header { 237 | background-color: #779ecb; 238 | } 239 | .manage-articleTypes-nav .delete-articleType-nav { 240 | color: #c9302c; 241 | } 242 | .manage-articleTypes-nav .add-articleType-nav-btn { 243 | float: right; 244 | } 245 | .sort-up { 246 | color: #449d44; 247 | } 248 | .sort-down { 249 | color: #337ab7; 250 | } 251 | 252 | /*CSS For custom blog info*/ 253 | /*.custom-blog .blog-info-box {*/ 254 | /*margin-left: 30px;*/ 255 | /*}*/ 256 | .custom-blog .info-header { 257 | color: #337ab7; 258 | } 259 | 260 | 261 | /*CSS For custom blog plugin*/ 262 | .custom-blog-plugin .blog-plugin-box { 263 | margin-left: 30px; 264 | margin-right: 30px; 265 | } 266 | .custom-blog-plugin th { 267 | text-align: center; 268 | } 269 | .custom-blog-plugin td { 270 | text-align: center; 271 | } 272 | .custom-blog-plugin .table-header { 273 | background-color: #779ecb; 274 | } 275 | .custom-blog-plugin .delete-blog-plugin { 276 | color: #c9302c; 277 | } 278 | .custom-blog-plugin .add-blog-plugin-btn { 279 | float: right; 280 | } 281 | 282 | /*CSS For account*/ 283 | .account { 284 | min-height: 250px; 285 | } 286 | .account .profile-header { 287 | margin-left: 135px; 288 | } 289 | .account .username { 290 | color: #337ab7; 291 | } 292 | .account .email { 293 | color: #337ab7; 294 | } 295 | 296 | /*CSS For login page*/ 297 | .login-page { 298 | margin-top: 200px; 299 | } 300 | -------------------------------------------------------------------------------- /app/static/css/prism.css: -------------------------------------------------------------------------------- 1 | /* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+abap+actionscript+apacheconf+apl+applescript+asciidoc+aspnet+autoit+autohotkey+bash+basic+batch+c+brainfuck+bison+csharp+cpp+coffeescript+ruby+css-extras+d+dart+diff+docker+eiffel+elixir+erlang+fsharp+fortran+gherkin+git+glsl+go+groovy+haml+handlebars+haskell+haxe+http+icon+inform7+ini+j+jade+java+json+julia+keyman+kotlin+latex+less+lolcode+lua+makefile+markdown+matlab+mel+mizar+monkey+nasm+nginx+nim+nix+nsis+objectivec+ocaml+oz+parigp+parser+pascal+perl+php+php-extras+powershell+processing+prolog+puppet+pure+python+q+qore+r+jsx+rest+rip+roboconf+crystal+rust+sas+sass+scss+scala+scheme+smalltalk+smarty+sql+stylus+swift+tcl+textile+twig+typescript+verilog+vhdl+vim+wiki+yaml */ 2 | /** 3 | * prism.js default theme for JavaScript, CSS and HTML 4 | * Based on dabblet (http://dabblet.com) 5 | * @author Lea Verou 6 | */ 7 | 8 | code[class*="language-"], 9 | pre[class*="language-"] { 10 | color: black; 11 | background: none; 12 | text-shadow: 0 1px white; 13 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; 14 | direction: ltr; 15 | text-align: left; 16 | white-space: pre; 17 | word-spacing: normal; 18 | word-break: normal; 19 | word-wrap: normal; 20 | line-height: 1.5; 21 | 22 | -moz-tab-size: 4; 23 | -o-tab-size: 4; 24 | tab-size: 4; 25 | 26 | -webkit-hyphens: none; 27 | -moz-hyphens: none; 28 | -ms-hyphens: none; 29 | hyphens: none; 30 | } 31 | 32 | pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, 33 | code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { 34 | text-shadow: none; 35 | background: #b3d4fc; 36 | } 37 | 38 | pre[class*="language-"]::selection, pre[class*="language-"] ::selection, 39 | code[class*="language-"]::selection, code[class*="language-"] ::selection { 40 | text-shadow: none; 41 | background: #b3d4fc; 42 | } 43 | 44 | @media print { 45 | code[class*="language-"], 46 | pre[class*="language-"] { 47 | text-shadow: none; 48 | } 49 | } 50 | 51 | /* Code blocks */ 52 | pre[class*="language-"] { 53 | padding: 1em; 54 | margin: .5em 0; 55 | overflow: auto; 56 | } 57 | 58 | :not(pre) > code[class*="language-"], 59 | pre[class*="language-"] { 60 | background: #f5f2f0; 61 | } 62 | 63 | /* Inline code */ 64 | :not(pre) > code[class*="language-"] { 65 | padding: .1em; 66 | border-radius: .3em; 67 | white-space: normal; 68 | } 69 | 70 | .token.comment, 71 | .token.prolog, 72 | .token.doctype, 73 | .token.cdata { 74 | color: slategray; 75 | } 76 | 77 | .token.punctuation { 78 | color: #999; 79 | } 80 | 81 | .namespace { 82 | opacity: .7; 83 | } 84 | 85 | .token.property, 86 | .token.tag, 87 | .token.boolean, 88 | .token.number, 89 | .token.constant, 90 | .token.symbol, 91 | .token.deleted { 92 | color: #905; 93 | } 94 | 95 | .token.selector, 96 | .token.attr-name, 97 | .token.string, 98 | .token.char, 99 | .token.builtin, 100 | .token.inserted { 101 | color: #690; 102 | } 103 | 104 | .token.operator, 105 | .token.entity, 106 | .token.url, 107 | .language-css .token.string, 108 | .style .token.string { 109 | color: #a67f59; 110 | background: hsla(0, 0%, 100%, .5); 111 | } 112 | 113 | .token.atrule, 114 | .token.attr-value, 115 | .token.keyword { 116 | color: #07a; 117 | } 118 | 119 | .token.function { 120 | color: #DD4A68; 121 | } 122 | 123 | .token.regex, 124 | .token.important, 125 | .token.variable { 126 | color: #e90; 127 | } 128 | 129 | .token.important, 130 | .token.bold { 131 | font-weight: bold; 132 | } 133 | .token.italic { 134 | font-style: italic; 135 | } 136 | 137 | .token.entity { 138 | cursor: help; 139 | } 140 | 141 | -------------------------------------------------------------------------------- /app/static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /app/static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /app/static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /app/static/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /app/static/images/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/images/background.jpg -------------------------------------------------------------------------------- /app/static/js/admin.js: -------------------------------------------------------------------------------- 1 | //JS For manage-articles when select articles or select comments 2 | $(document).ready(function () { 3 | $('#select-all').click(function () { 4 | if ($(this).prop('checked')) { 5 | $('.op_check').prop('checked', true); 6 | } else { 7 | $('.op_check').prop('checked', false); 8 | } 9 | }); 10 | }); 11 | 12 | //JS For submit article id to delete article 13 | function delCfm(articleId) { 14 | $('#cfmClick').click(function () { 15 | formSubmit(articleId); 16 | }); 17 | $('#delCfmModel').modal(); 18 | } 19 | function formSubmit(articleId) { 20 | $('#delForm' + articleId).submit(); 21 | } 22 | 23 | //JS For select articles to delete 24 | $(document).ready(function () { 25 | $('#delArtsCfm').click(function(){ 26 | $('#delArticlesForm').submit(); 27 | }); 28 | 29 | $('#delArticles').click(function () { 30 | if ($('.op_check').filter(':checked').size() > 0) { 31 | var articleIds = []; 32 | $('.op_check:checked').each(function(){ 33 | articleIds.push($(this).val()); 34 | }); 35 | var articleIdsJson = JSON.stringify(articleIds); 36 | $('#articleIds').val(articleIdsJson); 37 | $('#delArtsCfmModel').modal(); 38 | } else { 39 | $('#selArtsCfmModel').modal(); 40 | } 41 | }); 42 | }); 43 | 44 | //JS For confirm to delete a comment in articleDetails page 45 | function delCommentCfm(url) { 46 | $('#delCommentCfmClick').click(function(){ 47 | window.location.href = url; 48 | }); 49 | $('#delCommentCfmModel').modal(); 50 | } 51 | 52 | //JS For select comments to delete 53 | 54 | //function sub_JSON_data(commentIds) { 55 | // console.log(commentIds); 56 | // console.log(typeof commentIds); 57 | // $.ajax({ 58 | // type:'post', 59 | // url:'manage-comments/delete-comments', 60 | // data: commentIds 61 | // }); 62 | //} 63 | //注意,可以使用Ajax技术,但是批量删除评论的情况直接使用表单会简单,因为还需要考虑整个页面的处理 64 | 65 | $(document).ready(function(){ 66 | $('#delComments').click(function(){ 67 | if($('.op_check_com').filter(':checked').size() > 0) { 68 | var commentIds = []; 69 | $('.op_check_com:checked').each(function(){ 70 | commentIds.push($(this).val()); 71 | }); 72 | var commentIdsJson = JSON.stringify(commentIds); 73 | $('#commentIds').val(commentIdsJson); 74 | $('#delComsCfm').click(function() { 75 | $('#delCommentsForm').submit(); 76 | }); 77 | $('#delComsCfmModel').modal(); 78 | } else { 79 | $('#selComsCfmModal').modal(); 80 | } 81 | }); 82 | }); 83 | 84 | //JS For reply to a comment in manage-comments page 85 | function pop_commentForm(followId, articleId) { 86 | $('#follow').val(followId); 87 | $('#article').val(articleId); 88 | $('#commentFormModel').modal(); 89 | } 90 | 91 | //JS For add articleType 92 | $(document).ready(function() { 93 | $('.add-articleType-btn').click(function() { 94 | $('#addArticleTypeFormModel').modal(); 95 | }); 96 | }); 97 | 98 | //JS For confirm to delete an articleType 99 | function delArticleTypeCfm(url) { 100 | $('#delArticleTypeCfmClick').click(function(){ 101 | window.location.href = url; 102 | }); 103 | $('#delArticleTypeCfmModel').modal(); 104 | } 105 | 106 | //JS For edit articleType to get its info 107 | function get_articleType_info(url, id) { 108 | $.getJSON(url, function(data) { 109 | $('#editName').val(data.name); 110 | $('#editSetting_hide').val(data.setting_hide); 111 | $('#editIntroduction').val(data.introduction); 112 | $('#editMenus').val(data.menu); 113 | $('#articleType_id').val(id); 114 | $('#ModalTitle').text('修改博文分类:' + data.name); 115 | if (data.name == '未分类') { 116 | $('#editName').prop('readonly', true); 117 | $('#editIntroduction').prop('readonly', true); 118 | } else { 119 | $('#editName').prop('readonly', false); 120 | $('#editIntroduction').prop('readonly', false); 121 | } 122 | $('#editArticleTypeFormModel').modal(); 123 | }); 124 | } 125 | 126 | //JS For add articleType 127 | $(document).ready(function() { 128 | $('.add-articleType-nav-btn').click(function() { 129 | $('#addArticleTypeNavFormModel').modal(); 130 | }); 131 | }); 132 | 133 | //JS For edit articleTypeNav to get its info 134 | function get_articleTypeNav_info(url) { 135 | $.getJSON(url, function(data) { 136 | $('#editNavName').val(data.name); 137 | $('#nav_id').val(data.nav_id); 138 | $('#NavModalTitle').text('修改分类导航:' + data.name); 139 | $('#editArticleTypeNavFormModel').modal(); 140 | }); 141 | } 142 | 143 | //JS For confirm to delete an articleType nav 144 | function delArticleTypeNavCfm(url) { 145 | $('#delArticleTypeNavCfmClick').click(function(){ 146 | window.location.href = url; 147 | }); 148 | $('#delArticleTypeNavCfmModel').modal(); 149 | } 150 | 151 | //JS For editing blog info 152 | function get_blog_info(url) { 153 | $.getJSON(url, function(data) { 154 | console.log(data); 155 | $('#title').val(data.title); 156 | $('#signature').val(data.signature); 157 | $('#navbar').val(data.navbar); 158 | $('#editBlogInfoFormModal').modal(); 159 | }); 160 | } 161 | 162 | //JS For confirm to delete a plugin 163 | function delPluginCfm(url) { 164 | $('#delPluginCfmClick').click(function(){ 165 | window.location.href = url; 166 | }); 167 | $('#delPluginCfmModal').modal(); 168 | } 169 | 170 | //JS For change password 171 | function changePassword() { 172 | $('#changePasswordFormModal').modal(); 173 | } 174 | 175 | //JS For edit user info 176 | function EditUserInfo() { 177 | $('#editUserInfoFormModal').modal(); 178 | } 179 | -------------------------------------------------------------------------------- /app/static/js/commentReply.js: -------------------------------------------------------------------------------- 1 | 2 | //Rest the value when reply-dialog-box dismiss 3 | function undo_reply() { 4 | $('#follow').val(-1); 5 | } 6 | 7 | function go_to_reply(id, author_name) { 8 | $('html, body').animate({scrollTop: $('#submit-comment').offset().top}, 800); 9 | $('#follow').val(id); 10 | $('#reply-dialog-box').remove(); 11 | $('#submit-comment-container').prepend('
' + 12 | '' + 13 | '回复给' + $('
').text(author_name).html() +'
'); 14 | } 15 | 16 | //Reset the follow value when refresh page 17 | window.onload = function(){ 18 | $('#follow').val(-1); 19 | } 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/static/js/floatButton.js: -------------------------------------------------------------------------------- 1 | //JS For FloatButton to goTop, goBottom and refresh 2 | $(document).ready(function(){ 3 | //$('#goTop').click(function(){ 4 | // $(window).scrollTop(0); 5 | //}); 6 | $('#goTop').click(function(){ 7 | $('html, body').animate({scrollTop: '0px'}, 800); 8 | }); 9 | $('#refresh').click(function(){ 10 | window.location.reload(); 11 | }); 12 | $('#goBottom').click(function(){ 13 | $('html, body').animate({scrollTop: $('.footer').offset().top}, 800); 14 | }); 15 | }); 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/static/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /app/static/js/tinymce_setup.js: -------------------------------------------------------------------------------- 1 | //For submit articles 2 | tinymce.init({ 3 | selector: '#content', 4 | directionality:'ltr', 5 | language:'zh_CN', 6 | height:400, 7 | plugins: [ 8 | 'advlist autolink link image lists charmap print preview hr anchor pagebreak spellchecker', 9 | 'searchreplace wordcount visualblocks visualchars code fullscreen insertdatetime media nonbreaking', 10 | 'save table contextmenu directionality emoticons template paste textcolor', 11 | 'codesample', 12 | ], 13 | toolbar: 'insertfile undo redo | \ 14 | styleselect | \ 15 | bold italic | \ 16 | alignleft aligncenter alignright alignjustify | \ 17 | bullist numlist outdent indent | \ 18 | link image | \ 19 | print preview media fullpage | \ 20 | forecolor backcolor emoticons |\ 21 | codesample fontsizeselect fullscreen', 22 | fontsize_formats: '10pt 12pt 14pt 18pt 24pt 36pt', 23 | nonbreaking_force_tab: true 24 | }); 25 | 26 | //For add plugin 27 | tinymce.init({ 28 | selector: '#pluginContent', 29 | directionality:'ltr', 30 | language:'zh_CN', 31 | plugins: [ 32 | 'advlist autolink link image lists charmap print preview hr anchor pagebreak spellchecker', 33 | 'searchreplace wordcount visualblocks visualchars code fullscreen insertdatetime media nonbreaking', 34 | 'save table contextmenu directionality emoticons template paste textcolor', 35 | 'codesample', 36 | ], 37 | }); 38 | -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/jquery.tinymce.min.js: -------------------------------------------------------------------------------- 1 | !function(a){function b(){function b(a){"remove"===a&&this.each(function(a,b){var c=e(b);c&&c.remove()}),this.find("span.mceEditor,div.mceEditor").each(function(a,b){var c=tinymce.get(b.id.replace(/_parent$/,""));c&&c.remove()})}function d(a){var c,d=this;if(null!=a)b.call(d),d.each(function(b,c){var d;(d=tinymce.get(c.id))&&d.setContent(a)});else if(d.length>0&&(c=tinymce.get(d[0].id)))return c.getContent()}function e(a){var b=null;return a&&a.id&&g.tinymce&&(b=tinymce.get(a.id)),b}function f(a){return!!(a&&a.length&&g.tinymce&&a.is(":tinymce"))}var h={};a.each(["text","html","val"],function(b,g){var i=h[g]=a.fn[g],j="text"===g;a.fn[g]=function(b){var g=this;if(!f(g))return i.apply(g,arguments);if(b!==c)return d.call(g.filter(":tinymce"),b),i.apply(g.not(":tinymce"),arguments),g;var h="",k=arguments;return(j?g:g.eq(0)).each(function(b,c){var d=e(c);h+=d?j?d.getContent().replace(/<(?:"[^"]*"|'[^']*'|[^'">])*>/g,""):d.getContent({save:!0}):i.apply(a(c),k)}),h}}),a.each(["append","prepend"],function(b,d){var g=h[d]=a.fn[d],i="prepend"===d;a.fn[d]=function(a){var b=this;return f(b)?a!==c?("string"==typeof a&&b.filter(":tinymce").each(function(b,c){var d=e(c);d&&d.setContent(i?a+d.getContent():d.getContent()+a)}),g.apply(b.not(":tinymce"),arguments),b):void 0:g.apply(b,arguments)}}),a.each(["remove","replaceWith","replaceAll","empty"],function(c,d){var e=h[d]=a.fn[d];a.fn[d]=function(){return b.call(this,d),e.apply(this,arguments)}}),h.attr=a.fn.attr,a.fn.attr=function(b,g){var i=this,j=arguments;if(!b||"value"!==b||!f(i))return g!==c?h.attr.apply(i,j):h.attr.apply(i,j);if(g!==c)return d.call(i.filter(":tinymce"),g),h.attr.apply(i.not(":tinymce"),j),i;var k=i[0],l=e(k);return l?l.getContent({save:!0}):h.attr.apply(a(k),j)}}var c,d,e,f=[],g=window;a.fn.tinymce=function(c){function h(){var d=[],f=0;e||(b(),e=!0),l.each(function(a,b){var e,g=b.id,h=c.oninit;g||(b.id=g=tinymce.DOM.uniqueId()),tinymce.get(g)||(e=new tinymce.Editor(g,c,tinymce.EditorManager),d.push(e),e.on("init",function(){var a,b=h;l.css("visibility",""),h&&++f==d.length&&("string"==typeof b&&(a=-1===b.indexOf(".")?null:tinymce.resolve(b.replace(/\.\w+$/,"")),b=tinymce.resolve(b)),b.apply(a||tinymce,d))}))}),a.each(d,function(a,b){b.render()})}var i,j,k,l=this,m="";if(!l.length)return l;if(!c)return window.tinymce?tinymce.get(l[0].id):null;if(l.css("visibility","hidden"),g.tinymce||d||!(i=c.script_url))1===d?f.push(h):h();else{d=1,j=i.substring(0,i.lastIndexOf("/")),-1!=i.indexOf(".min")&&(m=".min"),g.tinymce=g.tinyMCEPreInit||{base:j,suffix:m},-1!=i.indexOf("gzip")&&(k=c.language||"en",i=i+(/\?/.test(i)?"&":"?")+"js=true&core=true&suffix="+escape(m)+"&themes="+escape(c.theme||"modern")+"&plugins="+escape(c.plugins||"")+"&languages="+(k||""),g.tinyMCE_GZ||(g.tinyMCE_GZ={start:function(){function b(a){tinymce.ScriptLoader.markDone(tinymce.baseURI.toAbsolute(a))}b("langs/"+k+".js"),b("themes/"+c.theme+"/theme"+m+".js"),b("themes/"+c.theme+"/langs/"+k+".js"),a.each(c.plugins.split(","),function(a,c){c&&(b("plugins/"+c+"/plugin"+m+".js"),b("plugins/"+c+"/langs/"+k+".js"))})},end:function(){}}));var n=document.createElement("script");n.type="text/javascript",n.onload=n.onreadystatechange=function(b){b=b||window.event,2===d||"load"!=b.type&&!/complete|loaded/.test(n.readyState)||(tinymce.dom.Event.domLoaded=1,d=2,c.script_loaded&&c.script_loaded(),h(),a.each(f,function(a,b){b()}))},n.src=i,document.body.appendChild(n)}return l},a.extend(a.expr[":"],{tinymce:function(a){var b;return a.id&&"tinymce"in window&&(b=tinymce.get(a.id),b&&b.editorManager===tinymce)?!0:!1}})}(jQuery); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/langs/readme.md: -------------------------------------------------------------------------------- 1 | This is where language files should be placed. 2 | 3 | Please DO NOT translate these directly use this service: https://www.transifex.com/projects/p/tinymce/ 4 | -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/advlist/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("advlist",function(a){function b(a,b){var c=[];return tinymce.each(b.split(/[ ,]/),function(a){c.push({text:a.replace(/\-/g," ").replace(/\b\w/g,function(a){return a.toUpperCase()}),data:"default"==a?"":a})}),c}function c(b,c){a.undoManager.transact(function(){var d,e=a.dom,f=a.selection;d=e.getParent(f.getNode(),"ol,ul"),d&&d.nodeName==b&&c!==!1||a.execCommand("UL"==b?"InsertUnorderedList":"InsertOrderedList"),c=c===!1?g[b]:c,g[b]=c,d=e.getParent(f.getNode(),"ol,ul"),d&&(e.setStyle(d,"listStyleType",c?c:null),d.removeAttribute("data-mce-style")),a.focus()})}function d(b){var c=a.dom.getStyle(a.dom.getParent(a.selection.getNode(),"ol,ul"),"listStyleType")||"";b.control.items().each(function(a){a.active(a.settings.data===c)})}var e,f,g={};e=b("OL",a.getParam("advlist_number_styles","default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman")),f=b("UL",a.getParam("advlist_bullet_styles","default,circle,disc,square")),a.addButton("numlist",{type:"splitbutton",tooltip:"Numbered list",menu:e,onshow:d,onselect:function(a){c("OL",a.control.settings.data)},onclick:function(){c("OL",!1)}}),a.addButton("bullist",{type:"splitbutton",tooltip:"Bullet list",menu:f,onshow:d,onselect:function(a){c("UL",a.control.settings.data)},onclick:function(){c("UL",!1)}})}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/anchor/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("anchor",function(a){function b(){var b=a.selection.getNode(),c="",d="A"==b.tagName&&""===a.dom.getAttrib(b,"href");d&&(c=b.name||b.id||""),a.windowManager.open({title:"Anchor",body:{type:"textbox",name:"name",size:40,label:"Name",value:c},onsubmit:function(c){var e=c.data.name;d?b.id=e:(a.selection.collapse(!0),a.execCommand("mceInsertContent",!1,a.dom.createHTML("a",{id:e})))}})}a.addCommand("mceAnchor",b),a.addButton("anchor",{icon:"anchor",tooltip:"Anchor",onclick:b,stateSelector:"a:not([href])"}),a.addMenuItem("anchor",{icon:"anchor",text:"Anchor",context:"insert",onclick:b})}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/autolink/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("autolink",function(a){function b(a){e(a,-1,"(",!0)}function c(a){e(a,0,"",!0)}function d(a){e(a,-1,"",!1)}function e(a,b,c){function d(a,b){if(0>b&&(b=0),3==a.nodeType){var c=a.data.length;b>c&&(b=c)}return b}function e(a,b){1!=a.nodeType||a.hasChildNodes()?h.setStart(a,d(a,b)):h.setStartBefore(a)}function f(a,b){1!=a.nodeType||a.hasChildNodes()?h.setEnd(a,d(a,b)):h.setEndAfter(a)}var h,i,j,k,l,m,n,o,p,q;if("A"!=a.selection.getNode().tagName){if(h=a.selection.getRng(!0).cloneRange(),h.startOffset<5){if(o=h.endContainer.previousSibling,!o){if(!h.endContainer.firstChild||!h.endContainer.firstChild.nextSibling)return;o=h.endContainer.firstChild.nextSibling}if(p=o.length,e(o,p),f(o,p),h.endOffset<5)return;i=h.endOffset,k=o}else{if(k=h.endContainer,3!=k.nodeType&&k.firstChild){for(;3!=k.nodeType&&k.firstChild;)k=k.firstChild;3==k.nodeType&&(e(k,0),f(k,k.nodeValue.length))}i=1==h.endOffset?2:h.endOffset-1-b}j=i;do e(k,i>=2?i-2:0),f(k,i>=1?i-1:0),i-=1,q=h.toString();while(" "!=q&&""!==q&&160!=q.charCodeAt(0)&&i-2>=0&&q!=c);h.toString()==c||160==h.toString().charCodeAt(0)?(e(k,i),f(k,j),i+=1):0===h.startOffset?(e(k,0),f(k,j)):(e(k,i),f(k,j)),m=h.toString(),"."==m.charAt(m.length-1)&&f(k,j-1),m=h.toString(),n=m.match(g),n&&("www."==n[1]?n[1]="http://www.":/@$/.test(n[1])&&!/^mailto:/.test(n[1])&&(n[1]="mailto:"+n[1]),l=a.selection.getBookmark(),a.selection.setRng(h),a.execCommand("createlink",!1,n[1]+n[2]),a.selection.moveToBookmark(l),a.nodeChanged())}}var f,g=/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|(?:mailto:)?[A-Z0-9._%+\-]+@)(.+)$/i;return a.settings.autolink_pattern&&(g=a.settings.autolink_pattern),a.on("keydown",function(b){return 13==b.keyCode?d(a):void 0}),tinymce.Env.ie?void a.on("focus",function(){if(!f){f=!0;try{a.execCommand("AutoUrlDetect",!1,!0)}catch(b){}}}):(a.on("keypress",function(c){return 41==c.keyCode?b(a):void 0}),void a.on("keyup",function(b){return 32==b.keyCode?c(a):void 0}))}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/autoresize/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("autoresize",function(a){function b(){return a.plugins.fullscreen&&a.plugins.fullscreen.isFullscreen()}function c(d){var g,h,i,j,k,l,m,n,o,p,q,r,s=tinymce.DOM;if(h=a.getDoc()){if(i=h.body,j=h.documentElement,k=e.autoresize_min_height,!i||d&&"setcontent"===d.type&&d.initial||b())return void(i&&j&&(i.style.overflowY="auto",j.style.overflowY="auto"));m=a.dom.getStyle(i,"margin-top",!0),n=a.dom.getStyle(i,"margin-bottom",!0),o=a.dom.getStyle(i,"padding-top",!0),p=a.dom.getStyle(i,"padding-bottom",!0),q=a.dom.getStyle(i,"border-top-width",!0),r=a.dom.getStyle(i,"border-bottom-width",!0),l=i.offsetHeight+parseInt(m,10)+parseInt(n,10)+parseInt(o,10)+parseInt(p,10)+parseInt(q,10)+parseInt(r,10),(isNaN(l)||0>=l)&&(l=tinymce.Env.ie?i.scrollHeight:tinymce.Env.webkit&&0===i.clientHeight?0:i.offsetHeight),l>e.autoresize_min_height&&(k=l),e.autoresize_max_height&&l>e.autoresize_max_height?(k=e.autoresize_max_height,i.style.overflowY="auto",j.style.overflowY="auto"):(i.style.overflowY="hidden",j.style.overflowY="hidden",i.scrollTop=0),k!==f&&(g=k-f,s.setStyle(a.iframeElement,"height",k+"px"),f=k,tinymce.isWebKit&&0>g&&c(d))}}function d(b,e,f){tinymce.util.Delay.setEditorTimeout(a,function(){c({}),b--?d(b,e,f):f&&f()},e)}var e=a.settings,f=0;a.settings.inline||(e.autoresize_min_height=parseInt(a.getParam("autoresize_min_height",a.getElement().offsetHeight),10),e.autoresize_max_height=parseInt(a.getParam("autoresize_max_height",0),10),a.on("init",function(){var b,c;b=a.getParam("autoresize_overflow_padding",1),c=a.getParam("autoresize_bottom_margin",50),b!==!1&&a.dom.setStyles(a.getBody(),{paddingLeft:b,paddingRight:b}),c!==!1&&a.dom.setStyles(a.getBody(),{paddingBottom:c})}),a.on("nodechange setcontent keyup FullscreenStateChanged",c),a.getParam("autoresize_on_init",!0)&&a.on("init",function(){d(20,100,function(){d(5,1e3)})}),a.addCommand("mceAutoResize",c))}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/autosave/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce._beforeUnloadHandler=function(){var a;return tinymce.each(tinymce.editors,function(b){b.plugins.autosave&&b.plugins.autosave.storeDraft(),!a&&b.isDirty()&&b.getParam("autosave_ask_before_unload",!0)&&(a=b.translate("You have unsaved changes are you sure you want to navigate away?"))}),a},tinymce.PluginManager.add("autosave",function(a){function b(a,b){var c={s:1e3,m:6e4};return a=/^(\d+)([ms]?)$/.exec(""+(a||b)),(a[2]?c[a[2]]:1)*parseInt(a,10)}function c(){var a=parseInt(n.getItem(k+"time"),10)||0;return(new Date).getTime()-a>m.autosave_retention?(d(!1),!1):!0}function d(b){n.removeItem(k+"draft"),n.removeItem(k+"time"),b!==!1&&a.fire("RemoveDraft")}function e(){!j()&&a.isDirty()&&(n.setItem(k+"draft",a.getContent({format:"raw",no_events:!0})),n.setItem(k+"time",(new Date).getTime()),a.fire("StoreDraft"))}function f(){c()&&(a.setContent(n.getItem(k+"draft"),{format:"raw"}),a.fire("RestoreDraft"))}function g(){l||(setInterval(function(){a.removed||e()},m.autosave_interval),l=!0)}function h(){var b=this;b.disabled(!c()),a.on("StoreDraft RestoreDraft RemoveDraft",function(){b.disabled(!c())}),g()}function i(){a.undoManager.beforeChange(),f(),d(),a.undoManager.add()}function j(b){var c=a.settings.forced_root_block;return b=tinymce.trim("undefined"==typeof b?a.getBody().innerHTML:b),""===b||new RegExp("^<"+c+"[^>]*>((\xa0| |[ ]|]*>)+?|)|
$","i").test(b)}var k,l,m=a.settings,n=tinymce.util.LocalStorage;k=m.autosave_prefix||"tinymce-autosave-{path}{query}-{id}-",k=k.replace(/\{path\}/g,document.location.pathname),k=k.replace(/\{query\}/g,document.location.search),k=k.replace(/\{id\}/g,a.id),m.autosave_interval=b(m.autosave_interval,"30s"),m.autosave_retention=b(m.autosave_retention,"20m"),a.addButton("restoredraft",{title:"Restore last draft",onclick:i,onPostRender:h}),a.addMenuItem("restoredraft",{text:"Restore last draft",onclick:i,onPostRender:h,context:"file"}),a.settings.autosave_restore_when_empty!==!1&&(a.on("init",function(){c()&&j()&&f()}),a.on("saveContent",function(){d()})),window.onbeforeunload=tinymce._beforeUnloadHandler,this.hasDraft=c,this.storeDraft=e,this.restoreDraft=f,this.removeDraft=d,this.isEmpty=j}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/bbcode/plugin.min.js: -------------------------------------------------------------------------------- 1 | !function(){tinymce.create("tinymce.plugins.BBCodePlugin",{init:function(a){var b=this,c=a.getParam("bbcode_dialect","punbb").toLowerCase();a.on("beforeSetContent",function(a){a.content=b["_"+c+"_bbcode2html"](a.content)}),a.on("postProcess",function(a){a.set&&(a.content=b["_"+c+"_bbcode2html"](a.content)),a.get&&(a.content=b["_"+c+"_html2bbcode"](a.content))})},getInfo:function(){return{longname:"BBCode Plugin",author:"Ephox Corp",authorurl:"http://www.tinymce.com",infourl:"http://www.tinymce.com/wiki.php/Plugin:bbcode"}},_punbb_html2bbcode:function(a){function b(b,c){a=a.replace(b,c)}return a=tinymce.trim(a),b(/(.*?)<\/a>/gi,"[url=$1]$2[/url]"),b(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),b(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),b(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),b(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),b(/(.*?)<\/span>/gi,"[color=$1]$2[/color]"),b(/(.*?)<\/font>/gi,"[color=$1]$2[/color]"),b(/(.*?)<\/span>/gi,"[size=$1]$2[/size]"),b(/(.*?)<\/font>/gi,"$1"),b(//gi,"[img]$1[/img]"),b(/(.*?)<\/span>/gi,"[code]$1[/code]"),b(/(.*?)<\/span>/gi,"[quote]$1[/quote]"),b(/(.*?)<\/strong>/gi,"[code][b]$1[/b][/code]"),b(/(.*?)<\/strong>/gi,"[quote][b]$1[/b][/quote]"),b(/(.*?)<\/em>/gi,"[code][i]$1[/i][/code]"),b(/(.*?)<\/em>/gi,"[quote][i]$1[/i][/quote]"),b(/(.*?)<\/u>/gi,"[code][u]$1[/u][/code]"),b(/(.*?)<\/u>/gi,"[quote][u]$1[/u][/quote]"),b(/<\/(strong|b)>/gi,"[/b]"),b(/<(strong|b)>/gi,"[b]"),b(/<\/(em|i)>/gi,"[/i]"),b(/<(em|i)>/gi,"[i]"),b(/<\/u>/gi,"[/u]"),b(/(.*?)<\/span>/gi,"[u]$1[/u]"),b(//gi,"[u]"),b(/]*>/gi,"[quote]"),b(/<\/blockquote>/gi,"[/quote]"),b(/
/gi,"\n"),b(//gi,"\n"),b(/
/gi,"\n"),b(/

/gi,""),b(/<\/p>/gi,"\n"),b(/ |\u00a0/gi," "),b(/"/gi,'"'),b(/</gi,"<"),b(/>/gi,">"),b(/&/gi,"&"),a},_punbb_bbcode2html:function(a){function b(b,c){a=a.replace(b,c)}return a=tinymce.trim(a),b(/\n/gi,"
"),b(/\[b\]/gi,""),b(/\[\/b\]/gi,""),b(/\[i\]/gi,""),b(/\[\/i\]/gi,""),b(/\[u\]/gi,""),b(/\[\/u\]/gi,""),b(/\[url=([^\]]+)\](.*?)\[\/url\]/gi,'$2'),b(/\[url\](.*?)\[\/url\]/gi,'$1'),b(/\[img\](.*?)\[\/img\]/gi,''),b(/\[color=(.*?)\](.*?)\[\/color\]/gi,'$2'),b(/\[code\](.*?)\[\/code\]/gi,'$1 '),b(/\[quote.*?\](.*?)\[\/quote\]/gi,'$1 '),a}}),tinymce.PluginManager.add("bbcode",tinymce.plugins.BBCodePlugin)}(); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/charmap/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("charmap",function(a){function b(){return[["160","no-break space"],["173","soft hyphen"],["34","quotation mark"],["162","cent sign"],["8364","euro sign"],["163","pound sign"],["165","yen sign"],["169","copyright sign"],["174","registered sign"],["8482","trade mark sign"],["8240","per mille sign"],["181","micro sign"],["183","middle dot"],["8226","bullet"],["8230","three dot leader"],["8242","minutes / feet"],["8243","seconds / inches"],["167","section sign"],["182","paragraph sign"],["223","sharp s / ess-zed"],["8249","single left-pointing angle quotation mark"],["8250","single right-pointing angle quotation mark"],["171","left pointing guillemet"],["187","right pointing guillemet"],["8216","left single quotation mark"],["8217","right single quotation mark"],["8220","left double quotation mark"],["8221","right double quotation mark"],["8218","single low-9 quotation mark"],["8222","double low-9 quotation mark"],["60","less-than sign"],["62","greater-than sign"],["8804","less-than or equal to"],["8805","greater-than or equal to"],["8211","en dash"],["8212","em dash"],["175","macron"],["8254","overline"],["164","currency sign"],["166","broken bar"],["168","diaeresis"],["161","inverted exclamation mark"],["191","turned question mark"],["710","circumflex accent"],["732","small tilde"],["176","degree sign"],["8722","minus sign"],["177","plus-minus sign"],["247","division sign"],["8260","fraction slash"],["215","multiplication sign"],["185","superscript one"],["178","superscript two"],["179","superscript three"],["188","fraction one quarter"],["189","fraction one half"],["190","fraction three quarters"],["402","function / florin"],["8747","integral"],["8721","n-ary sumation"],["8734","infinity"],["8730","square root"],["8764","similar to"],["8773","approximately equal to"],["8776","almost equal to"],["8800","not equal to"],["8801","identical to"],["8712","element of"],["8713","not an element of"],["8715","contains as member"],["8719","n-ary product"],["8743","logical and"],["8744","logical or"],["172","not sign"],["8745","intersection"],["8746","union"],["8706","partial differential"],["8704","for all"],["8707","there exists"],["8709","diameter"],["8711","backward difference"],["8727","asterisk operator"],["8733","proportional to"],["8736","angle"],["180","acute accent"],["184","cedilla"],["170","feminine ordinal indicator"],["186","masculine ordinal indicator"],["8224","dagger"],["8225","double dagger"],["192","A - grave"],["193","A - acute"],["194","A - circumflex"],["195","A - tilde"],["196","A - diaeresis"],["197","A - ring above"],["198","ligature AE"],["199","C - cedilla"],["200","E - grave"],["201","E - acute"],["202","E - circumflex"],["203","E - diaeresis"],["204","I - grave"],["205","I - acute"],["206","I - circumflex"],["207","I - diaeresis"],["208","ETH"],["209","N - tilde"],["210","O - grave"],["211","O - acute"],["212","O - circumflex"],["213","O - tilde"],["214","O - diaeresis"],["216","O - slash"],["338","ligature OE"],["352","S - caron"],["217","U - grave"],["218","U - acute"],["219","U - circumflex"],["220","U - diaeresis"],["221","Y - acute"],["376","Y - diaeresis"],["222","THORN"],["224","a - grave"],["225","a - acute"],["226","a - circumflex"],["227","a - tilde"],["228","a - diaeresis"],["229","a - ring above"],["230","ligature ae"],["231","c - cedilla"],["232","e - grave"],["233","e - acute"],["234","e - circumflex"],["235","e - diaeresis"],["236","i - grave"],["237","i - acute"],["238","i - circumflex"],["239","i - diaeresis"],["240","eth"],["241","n - tilde"],["242","o - grave"],["243","o - acute"],["244","o - circumflex"],["245","o - tilde"],["246","o - diaeresis"],["248","o slash"],["339","ligature oe"],["353","s - caron"],["249","u - grave"],["250","u - acute"],["251","u - circumflex"],["252","u - diaeresis"],["253","y - acute"],["254","thorn"],["255","y - diaeresis"],["913","Alpha"],["914","Beta"],["915","Gamma"],["916","Delta"],["917","Epsilon"],["918","Zeta"],["919","Eta"],["920","Theta"],["921","Iota"],["922","Kappa"],["923","Lambda"],["924","Mu"],["925","Nu"],["926","Xi"],["927","Omicron"],["928","Pi"],["929","Rho"],["931","Sigma"],["932","Tau"],["933","Upsilon"],["934","Phi"],["935","Chi"],["936","Psi"],["937","Omega"],["945","alpha"],["946","beta"],["947","gamma"],["948","delta"],["949","epsilon"],["950","zeta"],["951","eta"],["952","theta"],["953","iota"],["954","kappa"],["955","lambda"],["956","mu"],["957","nu"],["958","xi"],["959","omicron"],["960","pi"],["961","rho"],["962","final sigma"],["963","sigma"],["964","tau"],["965","upsilon"],["966","phi"],["967","chi"],["968","psi"],["969","omega"],["8501","alef symbol"],["982","pi symbol"],["8476","real part symbol"],["978","upsilon - hook symbol"],["8472","Weierstrass p"],["8465","imaginary part"],["8592","leftwards arrow"],["8593","upwards arrow"],["8594","rightwards arrow"],["8595","downwards arrow"],["8596","left right arrow"],["8629","carriage return"],["8656","leftwards double arrow"],["8657","upwards double arrow"],["8658","rightwards double arrow"],["8659","downwards double arrow"],["8660","left right double arrow"],["8756","therefore"],["8834","subset of"],["8835","superset of"],["8836","not a subset of"],["8838","subset of or equal to"],["8839","superset of or equal to"],["8853","circled plus"],["8855","circled times"],["8869","perpendicular"],["8901","dot operator"],["8968","left ceiling"],["8969","right ceiling"],["8970","left floor"],["8971","right floor"],["9001","left-pointing angle bracket"],["9002","right-pointing angle bracket"],["9674","lozenge"],["9824","black spade suit"],["9827","black club suit"],["9829","black heart suit"],["9830","black diamond suit"],["8194","en space"],["8195","em space"],["8201","thin space"],["8204","zero width non-joiner"],["8205","zero width joiner"],["8206","left-to-right mark"],["8207","right-to-left mark"]]}function c(a){return tinymce.util.Tools.grep(a,function(a){return i(a)&&2==a.length})}function d(a){return i(a)?[].concat(c(a)):"function"==typeof a?a():[]}function e(b){var c=a.settings;return c.charmap&&(b=d(c.charmap)),c.charmap_append?[].concat(b).concat(d(c.charmap_append)):b}function f(){return e(b())}function g(b){a.fire("insertCustomChar",{chr:b}).chr,a.execCommand("mceInsertContent",!1,b)}function h(){function b(a){for(;a;){if("TD"==a.nodeName)return a;a=a.parentNode}}var c,d,e,h;c='';var i=f(),j=Math.min(i.length,25),k=Math.ceil(i.length/j);for(e=0;k>e;e++){for(c+="",d=0;j>d;d++){var l=e*j+d;if(l
'+(m?String.fromCharCode(parseInt(m[0],10)):" ")+"
"}else c+="
"}c+="";var n={type:"container",html:c,onclick:function(a){var c=a.target;/^(TD|DIV)$/.test(c.nodeName)&&b(c).firstChild&&(g(tinymce.trim(c.innerText||c.textContent)),a.ctrlKey||h.close())},onmouseover:function(a){var c=b(a.target);c&&c.firstChild?(h.find("#preview").text(c.firstChild.firstChild.data),h.find("#previewTitle").text(c.title)):(h.find("#preview").text(" "),h.find("#previewTitle").text(" "))}};h=a.windowManager.open({title:"Special character",spacing:10,padding:10,items:[n,{type:"container",layout:"flex",direction:"column",align:"center",spacing:5,minWidth:160,minHeight:160,items:[{type:"label",name:"preview",text:" ",style:"font-size: 40px; text-align: center",border:1,minWidth:140,minHeight:80},{type:"label",name:"previewTitle",text:" ",style:"text-align: center",border:1,minWidth:140,minHeight:80}]}],buttons:[{text:"Close",onclick:function(){h.close()}}]})}var i=tinymce.util.Tools.isArray;return a.addCommand("mceShowCharmap",h),a.addButton("charmap",{icon:"charmap",tooltip:"Special character",cmd:"mceShowCharmap"}),a.addMenuItem("charmap",{icon:"charmap",text:"Special character",cmd:"mceShowCharmap",context:"insert"}),{getCharMap:f,insertChar:g}}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/code/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("code",function(a){function b(){var b=a.windowManager.open({title:"Source code",body:{type:"textbox",name:"code",multiline:!0,minWidth:a.getParam("code_dialog_width",600),minHeight:a.getParam("code_dialog_height",Math.min(tinymce.DOM.getViewPort().h-200,500)),spellcheck:!1,style:"direction: ltr; text-align: left"},onSubmit:function(b){a.focus(),a.undoManager.transact(function(){a.setContent(b.data.code)}),a.selection.setCursorLocation(),a.nodeChanged()}});b.find("#code").value(a.getContent({source_view:!0}))}a.addCommand("mceCodeEditor",b),a.addButton("code",{icon:"code",tooltip:"Source code",onclick:b}),a.addMenuItem("code",{icon:"code",text:"Source code",context:"tools",onclick:b})}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/codesample/css/prism.css: -------------------------------------------------------------------------------- 1 | /* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript */ 2 | /** 3 | * prism.js default theme for JavaScript, CSS and HTML 4 | * Based on dabblet (http://dabblet.com) 5 | * @author Lea Verou 6 | */ 7 | 8 | code[class*="language-"], 9 | pre[class*="language-"] { 10 | color: black; 11 | text-shadow: 0 1px white; 12 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; 13 | direction: ltr; 14 | text-align: left; 15 | white-space: pre; 16 | word-spacing: normal; 17 | word-break: normal; 18 | word-wrap: normal; 19 | line-height: 1.5; 20 | 21 | -moz-tab-size: 4; 22 | -o-tab-size: 4; 23 | tab-size: 4; 24 | 25 | -webkit-hyphens: none; 26 | -moz-hyphens: none; 27 | -ms-hyphens: none; 28 | hyphens: none; 29 | } 30 | 31 | pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, 32 | code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { 33 | text-shadow: none; 34 | background: #b3d4fc; 35 | } 36 | 37 | pre[class*="language-"]::selection, pre[class*="language-"] ::selection, 38 | code[class*="language-"]::selection, code[class*="language-"] ::selection { 39 | text-shadow: none; 40 | background: #b3d4fc; 41 | } 42 | 43 | @media print { 44 | code[class*="language-"], 45 | pre[class*="language-"] { 46 | text-shadow: none; 47 | } 48 | } 49 | 50 | /* Code blocks */ 51 | pre[class*="language-"] { 52 | padding: 1em; 53 | margin: .5em 0; 54 | overflow: auto; 55 | } 56 | 57 | :not(pre) > code[class*="language-"], 58 | pre[class*="language-"] { 59 | background: #f5f2f0; 60 | } 61 | 62 | /* Inline code */ 63 | :not(pre) > code[class*="language-"] { 64 | padding: .1em; 65 | border-radius: .3em; 66 | } 67 | 68 | .token.comment, 69 | .token.prolog, 70 | .token.doctype, 71 | .token.cdata { 72 | color: slategray; 73 | } 74 | 75 | .token.punctuation { 76 | color: #999; 77 | } 78 | 79 | .namespace { 80 | opacity: .7; 81 | } 82 | 83 | .token.property, 84 | .token.tag, 85 | .token.boolean, 86 | .token.number, 87 | .token.constant, 88 | .token.symbol, 89 | .token.deleted { 90 | color: #905; 91 | } 92 | 93 | .token.selector, 94 | .token.attr-name, 95 | .token.string, 96 | .token.char, 97 | .token.builtin, 98 | .token.inserted { 99 | color: #690; 100 | } 101 | 102 | .token.operator, 103 | .token.entity, 104 | .token.url, 105 | .language-css .token.string, 106 | .style .token.string { 107 | color: #a67f59; 108 | background: hsla(0, 0%, 100%, .5); 109 | } 110 | 111 | .token.atrule, 112 | .token.attr-value, 113 | .token.keyword { 114 | color: #07a; 115 | } 116 | 117 | .token.function { 118 | color: #DD4A68; 119 | } 120 | 121 | .token.regex, 122 | .token.important, 123 | .token.variable { 124 | color: #e90; 125 | } 126 | 127 | .token.important, 128 | .token.bold { 129 | font-weight: bold; 130 | } 131 | .token.italic { 132 | font-style: italic; 133 | } 134 | 135 | .token.entity { 136 | cursor: help; 137 | } 138 | 139 | -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/colorpicker/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("colorpicker",function(a){function b(b,c){function d(a){var b=new tinymce.util.Color(a),c=b.toRgb();f.fromJSON({r:c.r,g:c.g,b:c.b,hex:b.toHex().substr(1)}),e(b.toHex())}function e(a){f.find("#preview")[0].getEl().style.background=a}var f=a.windowManager.open({title:"Color",items:{type:"container",layout:"flex",direction:"row",align:"stretch",padding:5,spacing:10,items:[{type:"colorpicker",value:c,onchange:function(){var a=this.rgb();f&&(f.find("#r").value(a.r),f.find("#g").value(a.g),f.find("#b").value(a.b),f.find("#hex").value(this.value().substr(1)),e(this.value()))}},{type:"form",padding:0,labelGap:5,defaults:{type:"textbox",size:7,value:"0",flex:1,spellcheck:!1,onchange:function(){var a,b,c=f.find("colorpicker")[0];return a=this.name(),b=this.value(),"hex"==a?(b="#"+b,d(b),void c.value(b)):(b={r:f.find("#r").value(),g:f.find("#g").value(),b:f.find("#b").value()},c.value(b),void d(b))}},items:[{name:"r",label:"R",autofocus:1},{name:"g",label:"G"},{name:"b",label:"B"},{name:"hex",label:"#",value:"000000"},{name:"preview",type:"container",border:1}]}]},onSubmit:function(){b("#"+this.toJSON().hex)}});d(c)}a.settings.color_picker_callback||(a.settings.color_picker_callback=b)}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/contextmenu/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("contextmenu",function(a){var b,c=a.settings.contextmenu_never_use_native;a.on("contextmenu",function(d){var e,f=a.getDoc();if(!d.ctrlKey||c){if(d.preventDefault(),tinymce.Env.mac&&tinymce.Env.webkit&&2==d.button&&f.caretRangeFromPoint&&a.selection.setRng(f.caretRangeFromPoint(d.x,d.y)),e=a.settings.contextmenu||"link image inserttable | cell row column deletetable",b)b.show();else{var g=[];tinymce.each(e.split(/[ ,]/),function(b){var c=a.menuItems[b];"|"==b&&(c={text:b}),c&&(c.shortcut="",g.push(c))});for(var h=0;h'}),a+=""}),a+=""}var d=[["cool","cry","embarassed","foot-in-mouth"],["frown","innocent","kiss","laughing"],["money-mouth","sealed","smile","surprised"],["tongue-out","undecided","wink","yell"]];a.addButton("emoticons",{type:"panelbutton",panel:{role:"application",autohide:!0,html:c,onclick:function(b){var c=a.dom.getParent(b.target,"a");c&&(a.insertContent(''+c.getAttribute('),this.hide())}},tooltip:"Emoticons"})}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/example/dialog.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

Custom dialog

5 | Input some text: 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/example/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("example",function(a,b){a.addButton("example",{text:"My button",icon:!1,onclick:function(){a.windowManager.open({title:"Example plugin",body:[{type:"textbox",name:"title",label:"Title"}],onsubmit:function(b){a.insertContent("Title: "+b.data.title)}})}}),a.addMenuItem("example",{text:"Example plugin",context:"tools",onclick:function(){a.windowManager.open({title:"TinyMCE site",url:b+"/dialog.html",width:600,height:400,buttons:[{text:"Insert",onclick:function(){var b=a.windowManager.getWindows()[0];a.insertContent(b.getContentWindow().document.getElementById("content").value),b.close()}},{text:"Close",onclick:"close"}]})}})}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/example_dependency/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("example_dependency",function(){},["example"]); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/fullpage/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("fullpage",function(a){function b(){var b=c();a.windowManager.open({title:"Document properties",data:b,defaults:{type:"textbox",size:40},body:[{name:"title",label:"Title"},{name:"keywords",label:"Keywords"},{name:"description",label:"Description"},{name:"robots",label:"Robots"},{name:"author",label:"Author"},{name:"docencoding",label:"Encoding"}],onSubmit:function(a){d(tinymce.extend(b,a.data))}})}function c(){function b(a,b){var c=a.attr(b);return c||""}var c,d,f=e(),g={};return g.fontface=a.getParam("fullpage_default_fontface",""),g.fontsize=a.getParam("fullpage_default_fontsize",""),c=f.firstChild,7==c.type&&(g.xml_pi=!0,d=/encoding="([^"]+)"/.exec(c.value),d&&(g.docencoding=d[1])),c=f.getAll("#doctype")[0],c&&(g.doctype=""),c=f.getAll("title")[0],c&&c.firstChild&&(g.title=c.firstChild.value),k(f.getAll("meta"),function(a){var b,c=a.attr("name"),d=a.attr("http-equiv");c?g[c.toLowerCase()]=a.attr("content"):"Content-Type"==d&&(b=/charset\s*=\s*(.*)\s*/gi.exec(a.attr("content")),b&&(g.docencoding=b[1]))}),c=f.getAll("html")[0],c&&(g.langcode=b(c,"lang")||b(c,"xml:lang")),g.stylesheets=[],tinymce.each(f.getAll("link"),function(a){"stylesheet"==a.attr("rel")&&g.stylesheets.push(a.attr("href"))}),c=f.getAll("body")[0],c&&(g.langdir=b(c,"dir"),g.style=b(c,"style"),g.visited_color=b(c,"vlink"),g.link_color=b(c,"link"),g.active_color=b(c,"alink")),g}function d(b){function c(a,b,c){a.attr(b,c?c:void 0)}function d(a){g.firstChild?g.insert(a,g.firstChild):g.append(a)}var f,g,h,j,m,n=a.dom;f=e(),g=f.getAll("head")[0],g||(j=f.getAll("html")[0],g=new l("head",1),j.firstChild?j.insert(g,j.firstChild,!0):j.append(g)),j=f.firstChild,b.xml_pi?(m='version="1.0"',b.docencoding&&(m+=' encoding="'+b.docencoding+'"'),7!=j.type&&(j=new l("xml",7),f.insert(j,f.firstChild,!0)),j.value=m):j&&7==j.type&&j.remove(),j=f.getAll("#doctype")[0],b.doctype?(j||(j=new l("#doctype",10),b.xml_pi?f.insert(j,f.firstChild):d(j)),j.value=b.doctype.substring(9,b.doctype.length-1)):j&&j.remove(),j=null,k(f.getAll("meta"),function(a){"Content-Type"==a.attr("http-equiv")&&(j=a)}),b.docencoding?(j||(j=new l("meta",1),j.attr("http-equiv","Content-Type"),j.shortEnded=!0,d(j)),j.attr("content","text/html; charset="+b.docencoding)):j&&j.remove(),j=f.getAll("title")[0],b.title?(j?j.empty():(j=new l("title",1),d(j)),j.append(new l("#text",3)).value=b.title):j&&j.remove(),k("keywords,description,author,copyright,robots".split(","),function(a){var c,e,g=f.getAll("meta"),h=b[a];for(c=0;c"))}function e(){return new tinymce.html.DomParser({validate:!1,root_name:"#document"}).parse(i)}function f(b){function c(a){return a.replace(/<\/?[A-Z]+/g,function(a){return a.toLowerCase()})}var d,f,h,l,m=b.content,n="",o=a.dom;if(!b.selection&&!("raw"==b.format&&i||b.source_view&&a.getParam("fullpage_hide_in_source_view"))){0!==m.length||b.source_view||(m=tinymce.trim(i)+"\n"+tinymce.trim(m)+"\n"+tinymce.trim(j)),m=m.replace(/<(\/?)BODY/gi,"<$1body"),d=m.indexOf("",d),i=c(m.substring(0,d+1)),f=m.indexOf("\n"),h=e(),k(h.getAll("style"),function(a){a.firstChild&&(n+=a.firstChild.value)}),l=h.getAll("body")[0],l&&o.setAttribs(a.getBody(),{style:l.attr("style")||"",dir:l.attr("dir")||"",vLink:l.attr("vlink")||"",link:l.attr("link")||"",aLink:l.attr("alink")||""}),o.remove("fullpage_styles");var p=a.getDoc().getElementsByTagName("head")[0];n&&(o.add(p,"style",{id:"fullpage_styles"},n),l=o.get("fullpage_styles"),l.styleSheet&&(l.styleSheet.cssText=n));var q={};tinymce.each(p.getElementsByTagName("link"),function(a){"stylesheet"==a.rel&&a.getAttribute("data-mce-fullpage")&&(q[a.href]=a)}),tinymce.each(h.getAll("link"),function(a){var b=a.attr("href");q[b]||"stylesheet"!=a.attr("rel")||o.add(p,"link",{rel:"stylesheet",text:"text/css",href:b,"data-mce-fullpage":"1"}),delete q[b]}),tinymce.each(q,function(a){a.parentNode.removeChild(a)})}}function g(){var b,c="",d="";return a.getParam("fullpage_default_xml_pi")&&(c+='\n'),c+=a.getParam("fullpage_default_doctype",""),c+="\n\n\n",(b=a.getParam("fullpage_default_title"))&&(c+=""+b+"\n"),(b=a.getParam("fullpage_default_encoding"))&&(c+='\n'),(b=a.getParam("fullpage_default_font_family"))&&(d+="font-family: "+b+";"),(b=a.getParam("fullpage_default_font_size"))&&(d+="font-size: "+b+";"),(b=a.getParam("fullpage_default_text_color"))&&(d+="color: "+b+";"),c+="\n\n"}function h(b){b.selection||b.source_view&&a.getParam("fullpage_hide_in_source_view")||(b.content=tinymce.trim(i)+"\n"+tinymce.trim(b.content)+"\n"+tinymce.trim(j))}var i,j,k=tinymce.each,l=tinymce.html.Node;a.addCommand("mceFullPageProperties",b),a.addButton("fullpage",{title:"Document properties",cmd:"mceFullPageProperties"}),a.addMenuItem("fullpage",{text:"Document properties",cmd:"mceFullPageProperties",context:"file"}),a.on("BeforeSetContent",f),a.on("GetContent",h)}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/fullscreen/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("fullscreen",function(a){function b(){var a,b,c=window,d=document,e=d.body;return e.offsetWidth&&(a=e.offsetWidth,b=e.offsetHeight),c.innerWidth&&c.innerHeight&&(a=c.innerWidth,b=c.innerHeight),{w:a,h:b}}function c(){var a=tinymce.DOM.getViewPort();return{x:a.x,y:a.y}}function d(a){scrollTo(a.x,a.y)}function e(){function e(){m.setStyle(p,"height",b().h-(o.clientHeight-p.clientHeight))}var n,o,p,q,r=document.body,s=document.documentElement;l=!l,o=a.getContainer(),n=o.style,p=a.getContentAreaContainer().firstChild,q=p.style,l?(k=c(),f=q.width,g=q.height,q.width=q.height="100%",i=n.width,j=n.height,n.width=n.height="",m.addClass(r,"mce-fullscreen"),m.addClass(s,"mce-fullscreen"),m.addClass(o,"mce-fullscreen"),m.bind(window,"resize",e),e(),h=e):(q.width=f,q.height=g,i&&(n.width=i),j&&(n.height=j),m.removeClass(r,"mce-fullscreen"),m.removeClass(s,"mce-fullscreen"),m.removeClass(o,"mce-fullscreen"),m.unbind(window,"resize",h),d(k)),a.fire("FullscreenStateChanged",{state:l})}var f,g,h,i,j,k,l=!1,m=tinymce.DOM;return a.settings.inline?void 0:(a.on("init",function(){a.addShortcut("Meta+Alt+F","",e)}),a.on("remove",function(){h&&m.unbind(window,"resize",h)}),a.addCommand("mceFullScreen",e),a.addMenuItem("fullscreen",{text:"Fullscreen",shortcut:"Meta+Alt+F",selectable:!0,onClick:e,onPostRender:function(){var b=this;a.on("FullscreenStateChanged",function(a){b.active(a.state)})},context:"view"}),a.addButton("fullscreen",{tooltip:"Fullscreen",shortcut:"Meta+Alt+F",onClick:e,onPostRender:function(){var b=this;a.on("FullscreenStateChanged",function(a){b.active(a.state)})}}),{isFullscreen:function(){return l}})}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/hr/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("hr",function(a){a.addCommand("InsertHorizontalRule",function(){a.execCommand("mceInsertContent",!1,"
")}),a.addButton("hr",{icon:"hr",tooltip:"Horizontal line",cmd:"InsertHorizontalRule"}),a.addMenuItem("hr",{icon:"hr",text:"Horizontal line",cmd:"InsertHorizontalRule",context:"insert"})}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/image/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("image",function(a){function b(a,b){function c(a,c){d.parentNode&&d.parentNode.removeChild(d),b({width:a,height:c})}var d=document.createElement("img");d.onload=function(){c(Math.max(d.width,d.clientWidth),Math.max(d.height,d.clientHeight))},d.onerror=function(){c()};var e=d.style;e.visibility="hidden",e.position="fixed",e.bottom=e.left=0,e.width=e.height="auto",document.body.appendChild(d),d.src=a}function c(a,b,c){function d(a,c){return c=c||[],tinymce.each(a,function(a){var e={text:a.text||a.title};a.menu?e.menu=d(a.menu):(e.value=a.value,b(e)),c.push(e)}),c}return d(a,c||[])}function d(b){return function(){var c=a.settings.image_list;"string"==typeof c?tinymce.util.XHR.send({url:c,success:function(a){b(tinymce.util.JSON.parse(a))}}):"function"==typeof c?c(b):b(c)}}function e(d){function e(){var a,b,c,d;a=l.find("#width")[0],b=l.find("#height")[0],a&&b&&(c=a.value(),d=b.value(),l.find("#constrain")[0].checked()&&o&&p&&c&&d&&(o!=c?(d=Math.round(c/o*d),isNaN(d)||b.value(d)):(c=Math.round(d/p*c),isNaN(c)||a.value(c))),o=c,p=d)}function f(){function b(b){function c(){b.onload=b.onerror=null,a.selection&&(a.selection.select(b),a.nodeChanged())}b.onload=function(){s.width||s.height||!u||t.setAttribs(b,{width:b.clientWidth,height:b.clientHeight}),c()},b.onerror=c}var c,d;j(),e(),s=tinymce.extend(s,l.toJSON()),s.alt||(s.alt=""),s.title||(s.title=""),""===s.width&&(s.width=null),""===s.height&&(s.height=null),s.style||(s.style=null),s={src:s.src,alt:s.alt,title:s.title,width:s.width,height:s.height,style:s.style,caption:s.caption,"class":s["class"]},a.undoManager.transact(function(){function e(b){return a.schema.getTextBlockElements()[b.nodeName]}if(!s.src)return void(m&&(t.remove(m),a.focus(),a.nodeChanged()));if(""===s.title&&(s.title=null),m?t.setAttribs(m,s):(s.id="__mcenew",a.focus(),a.selection.setContent(t.createHTML("img",s)),m=t.get("__mcenew"),t.setAttrib(m,"id",null)),a.editorUpload.uploadImagesAuto(),s.caption===!1&&t.is(m.parentNode,"figure.image")&&(c=m.parentNode,t.insertAfter(m,c),t.remove(c)),s.caption!==!0)b(m);else if(!t.is(m.parentNode,"figure.image")){d=m,m=m.cloneNode(!0),c=t.create("figure",{"class":"image"}),c.appendChild(m),c.appendChild(t.create("figcaption",{contentEditable:!0},"Caption")),c.contentEditable=!1;var f=t.getParent(d,e);f?t.split(f,d,c):t.replace(c,d),a.selection.select(c)}})}function g(a){return a&&(a=a.replace(/px$/,"")),a}function h(c){var d,e,f,g=c.meta||{};q&&q.value(a.convertURL(this.value(),"src")),tinymce.each(g,function(a,b){l.find("#"+b).value(a)}),g.width||g.height||(d=a.convertURL(this.value(),"src"),e=a.settings.image_prepend_url,f=new RegExp("^(?:[a-z]+:)?//","i"),e&&!f.test(d)&&d.substring(0,e.length)!==e&&(d=e+d),this.value(d),b(a.documentBaseURI.toAbsolute(this.value()),function(a){a.width&&a.height&&u&&(o=a.width,p=a.height,l.find("#width").value(o),l.find("#height").value(p))}))}function i(a){if(a.margin){var b=a.margin.split(" ");switch(b.length){case 1:a["margin-top"]=a["margin-top"]||b[0],a["margin-right"]=a["margin-right"]||b[0],a["margin-bottom"]=a["margin-bottom"]||b[0],a["margin-left"]=a["margin-left"]||b[0];break;case 2:a["margin-top"]=a["margin-top"]||b[0],a["margin-right"]=a["margin-right"]||b[1],a["margin-bottom"]=a["margin-bottom"]||b[0],a["margin-left"]=a["margin-left"]||b[1];break;case 3:a["margin-top"]=a["margin-top"]||b[0],a["margin-right"]=a["margin-right"]||b[1],a["margin-bottom"]=a["margin-bottom"]||b[2],a["margin-left"]=a["margin-left"]||b[1];break;case 4:a["margin-top"]=a["margin-top"]||b[0],a["margin-right"]=a["margin-right"]||b[1],a["margin-bottom"]=a["margin-bottom"]||b[2],a["margin-left"]=a["margin-left"]||b[3]}delete a.margin}return a}function j(){function b(a){return a.length>0&&/^[0-9]+$/.test(a)&&(a+="px"),a}if(a.settings.image_advtab){var c=l.toJSON(),d=t.parseStyle(c.style);d=i(d),c.vspace&&(d["margin-top"]=d["margin-bottom"]=b(c.vspace)),c.hspace&&(d["margin-left"]=d["margin-right"]=b(c.hspace)),c.border&&(d["border-width"]=b(c.border)),l.find("#style").value(t.serializeStyle(t.parseStyle(t.serializeStyle(d))))}}function k(){if(a.settings.image_advtab){var b=l.toJSON(),c=t.parseStyle(b.style);l.find("#vspace").value(""),l.find("#hspace").value(""),c=i(c),(c["margin-top"]&&c["margin-bottom"]||c["margin-right"]&&c["margin-left"])&&(c["margin-top"]===c["margin-bottom"]?l.find("#vspace").value(g(c["margin-top"])):l.find("#vspace").value(""),c["margin-right"]===c["margin-left"]?l.find("#hspace").value(g(c["margin-right"])):l.find("#hspace").value("")),c["border-width"]&&l.find("#border").value(g(c["border-width"])),l.find("#style").value(t.serializeStyle(t.parseStyle(t.serializeStyle(c))))}}var l,m,n,o,p,q,r,s={},t=a.dom,u=a.settings.image_dimensions!==!1;m=a.selection.getNode(),n=t.getParent(m,"figure.image"),n&&(m=t.select("img",n)[0]),m&&("IMG"!=m.nodeName||m.getAttribute("data-mce-object")||m.getAttribute("data-mce-placeholder"))&&(m=null),m&&(o=t.getAttrib(m,"width"),p=t.getAttrib(m,"height"),s={src:t.getAttrib(m,"src"),alt:t.getAttrib(m,"alt"),title:t.getAttrib(m,"title"),"class":t.getAttrib(m,"class"),width:o,height:p,caption:!!n}),d&&(q={type:"listbox",label:"Image list",values:c(d,function(b){b.value=a.convertURL(b.value||b.url,"src")},[{text:"None",value:""}]),value:s.src&&a.convertURL(s.src,"src"),onselect:function(a){var b=l.find("#alt");(!b.value()||a.lastControl&&b.value()==a.lastControl.text())&&b.value(a.control.text()),l.find("#src").value(a.control.value()).fire("change")},onPostRender:function(){q=this}}),a.settings.image_class_list&&(r={name:"class",type:"listbox",label:"Class",values:c(a.settings.image_class_list,function(b){b.value&&(b.textStyle=function(){return a.formatter.getCssText({inline:"img",classes:[b.value]})})})});var v=[{name:"src",type:"filepicker",filetype:"image",label:"Source",autofocus:!0,onchange:h},q];a.settings.image_description!==!1&&v.push({name:"alt",type:"textbox",label:"Image description"}),a.settings.image_title&&v.push({name:"title",type:"textbox",label:"Image Title"}),u&&v.push({type:"container",label:"Dimensions",layout:"flex",direction:"row",align:"center",spacing:5,items:[{name:"width",type:"textbox",maxLength:5,size:3,onchange:e,ariaLabel:"Width"},{type:"label",text:"x"},{name:"height",type:"textbox",maxLength:5,size:3,onchange:e,ariaLabel:"Height"},{name:"constrain",type:"checkbox",checked:!0,text:"Constrain proportions"}]}),v.push(r),a.settings.image_caption&&tinymce.Env.ceFalse&&v.push({name:"caption",type:"checkbox",label:"Caption"}),a.settings.image_advtab?(m&&(m.style.marginLeft&&m.style.marginRight&&m.style.marginLeft===m.style.marginRight&&(s.hspace=g(m.style.marginLeft)),m.style.marginTop&&m.style.marginBottom&&m.style.marginTop===m.style.marginBottom&&(s.vspace=g(m.style.marginTop)),m.style.borderWidth&&(s.border=g(m.style.borderWidth)),s.style=a.dom.serializeStyle(a.dom.parseStyle(a.dom.getAttrib(m,"style")))),l=a.windowManager.open({title:"Insert/edit image",data:s,bodyType:"tabpanel",body:[{title:"General",type:"form",items:v},{title:"Advanced",type:"form",pack:"start",items:[{label:"Style",name:"style",type:"textbox",onchange:k},{type:"form",layout:"grid",packV:"start",columns:2,padding:0,alignH:["left","right"],defaults:{type:"textbox",maxWidth:50,onchange:j},items:[{label:"Vertical space",name:"vspace"},{label:"Horizontal space",name:"hspace"},{label:"Border",name:"border"}]}]}],onSubmit:f})):l=a.windowManager.open({title:"Insert/edit image",data:s,body:v,onSubmit:f})}a.on("preInit",function(){function b(a){var b=a.attr("class");return b&&/\bimage\b/.test(b)}function c(a){return function(c){function d(b){b.attr("contenteditable",a?"true":null)}for(var e,f=c.length;f--;)e=c[f],b(e)&&(e.attr("contenteditable",a?"false":null),tinymce.each(e.getAll("figcaption"),d))}}a.parser.addNodeFilter("figure",c(!0)),a.serializer.addNodeFilter("figure",c(!1))}),a.addButton("image",{icon:"image",tooltip:"Insert/edit image",onclick:d(e),stateSelector:"img:not([data-mce-object],[data-mce-placeholder]),figure.image"}),a.addMenuItem("image",{icon:"image",text:"Insert/edit image",onclick:d(e),context:"insert",prependToContext:!0}),a.addCommand("mceImage",d(e))}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/importcss/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("importcss",function(a){function b(a){var b=tinymce.Env.cacheSuffix;return"string"==typeof a&&(a=a.replace("?"+b,"").replace("&"+b,"")),a}function c(b){var c=a.settings,d=c.skin!==!1?c.skin||"lightgray":!1;if(d){var e=c.skin_url;return e=e?a.documentBaseURI.toAbsolute(e):tinymce.baseURL+"/skins/"+d,b===e+"/content"+(a.inline?".inline":"")+".min.css"}return!1}function d(a){return"string"==typeof a?function(b){return-1!==b.indexOf(a)}:a instanceof RegExp?function(b){return a.test(b)}:a}function e(d,e){function f(a,d){var i,j=a.href;if(j=b(j),j&&e(j,d)&&!c(j)){h(a.imports,function(a){f(a,!0)});try{i=a.cssRules||a.rules}catch(k){}h(i,function(a){a.styleSheet?f(a.styleSheet,!0):a.selectorText&&h(a.selectorText.split(","),function(a){g.push(tinymce.trim(a))})})}}var g=[],i={};h(a.contentCSS,function(a){i[a]=!0}),e||(e=function(a,b){return b||i[a]});try{h(d.styleSheets,function(a){f(a)})}catch(j){}return g}function f(b){var c,d=/^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(b);if(d){var e=d[1],f=d[2].substr(1).split(".").join(" "),g=tinymce.makeMap("a,img");return d[1]?(c={title:b},a.schema.getTextBlockElements()[e]?c.block=e:a.schema.getBlockElements()[e]||g[e.toLowerCase()]?c.selector=e:c.inline=e):d[2]&&(c={inline:"span",title:b.substr(1),classes:f}),a.settings.importcss_merge_classes!==!1?c.classes=f:c.attributes={"class":f},c}}var g=this,h=tinymce.each;a.on("renderFormatsMenu",function(b){var c=a.settings,i={},j=c.importcss_selector_converter||f,k=d(c.importcss_selector_filter),l=b.control;a.settings.importcss_append||l.items().remove();var m=[];tinymce.each(c.importcss_groups,function(a){a=tinymce.extend({},a),a.filter=d(a.filter),m.push(a)}),h(e(b.doc||a.getDoc(),d(c.importcss_file_filter)),function(b){if(-1===b.indexOf(".mce-")&&!i[b]&&(!k||k(b))){var c,d=j.call(g,b);if(d){var e=d.name||tinymce.DOM.uniqueId();if(m)for(var f=0;f'+d+"";var f=a.dom.getParent(a.selection.getStart(),"time");if(f)return void a.dom.setOuterHTML(f,d)}a.insertContent(d)}var d,e,f="Sun Mon Tue Wed Thu Fri Sat Sun".split(" "),g="Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(" "),h="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),i="January February March April May June July August September October November December".split(" "),j=[];a.addCommand("mceInsertDate",function(){c(a.getParam("insertdatetime_dateformat",a.translate("%Y-%m-%d")))}),a.addCommand("mceInsertTime",function(){c(a.getParam("insertdatetime_timeformat",a.translate("%H:%M:%S")))}),a.addButton("insertdatetime",{type:"splitbutton",title:"Insert date/time",onclick:function(){c(d||e)},menu:j}),tinymce.each(a.settings.insertdatetime_formats||["%H:%M:%S","%Y-%m-%d","%I:%M:%S %p","%D"],function(a){e||(e=a),j.push({text:b(a),onclick:function(){d=a,c(a)}})}),a.addMenuItem("insertdatetime",{icon:"date",text:"Insert date/time",menu:j,context:"insert"})}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/layer/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("layer",function(a){function b(a){do if(a.className&&-1!=a.className.indexOf("mceItemLayer"))return a;while(a=a.parentNode)}function c(b){var c=a.dom;tinymce.each(c.select("div,p",b),function(a){/^(absolute|relative|fixed)$/i.test(a.style.position)&&(a.hasVisual?c.addClass(a,"mceItemVisualAid"):c.removeClass(a,"mceItemVisualAid"),c.addClass(a,"mceItemLayer"))})}function d(c){var d,e,f=[],g=b(a.selection.getNode()),h=-1,i=-1;for(e=[],tinymce.walk(a.getBody(),function(a){1==a.nodeType&&/^(absolute|relative|static)$/i.test(a.style.position)&&e.push(a)},"childNodes"),d=0;dh&&e[d]==g&&(h=d);if(0>c){for(d=0;d-1?(e[h].style.zIndex=f[i],e[i].style.zIndex=f[h]):f[h]>0&&(e[h].style.zIndex=f[h]-1)}else{for(d=0;df[h]){i=d;break}i>-1?(e[h].style.zIndex=f[i],e[i].style.zIndex=f[h]):e[h].style.zIndex=f[h]+1}a.execCommand("mceRepaint")}function e(){var b=a.dom,c=b.getPos(b.getParent(a.selection.getNode(),"*")),d=a.getBody();a.dom.add(d,"div",{style:{position:"absolute",left:c.x,top:c.y>20?c.y:20,width:100,height:100},"class":"mceItemVisualAid mceItemLayer"},a.selection.getContent()||a.getLang("layer.content")),tinymce.Env.ie&&b.setHTML(d,d.innerHTML)}function f(){var c=b(a.selection.getNode());c||(c=a.dom.getParent(a.selection.getNode(),"DIV,P,IMG")),c&&("absolute"==c.style.position.toLowerCase()?(a.dom.setStyles(c,{position:"",left:"",top:"",width:"",height:""}),a.dom.removeClass(c,"mceItemVisualAid"),a.dom.removeClass(c,"mceItemLayer")):(c.style.left||(c.style.left="20px"),c.style.top||(c.style.top="20px"),c.style.width||(c.style.width=c.width?c.width+"px":"100px"),c.style.height||(c.style.height=c.height?c.height+"px":"100px"),c.style.position="absolute",a.dom.setAttrib(c,"data-mce-style",""),a.addVisual(a.getBody())),a.execCommand("mceRepaint"),a.nodeChanged())}a.addCommand("mceInsertLayer",e),a.addCommand("mceMoveForward",function(){d(1)}),a.addCommand("mceMoveBackward",function(){d(-1)}),a.addCommand("mceMakeAbsolute",function(){f()}),a.addButton("moveforward",{title:"layer.forward_desc",cmd:"mceMoveForward"}),a.addButton("movebackward",{title:"layer.backward_desc",cmd:"mceMoveBackward"}),a.addButton("absolute",{title:"layer.absolute_desc",cmd:"mceMakeAbsolute"}),a.addButton("insertlayer",{title:"layer.insertlayer_desc",cmd:"mceInsertLayer"}),a.on("init",function(){tinymce.Env.ie&&a.getDoc().execCommand("2D-Position",!1,!0)}),a.on("mouseup",function(c){var d=b(c.target);d&&a.dom.setAttrib(d,"data-mce-style","")}),a.on("mousedown",function(c){var d,e=c.target,f=a.getDoc();tinymce.Env.gecko&&(b(e)?"on"!==f.designMode&&(f.designMode="on",e=f.body,d=e.parentNode,d.removeChild(e),d.appendChild(e)):"on"==f.designMode&&(f.designMode="off"))}),a.on("NodeChange",c)}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/legacyoutput/plugin.min.js: -------------------------------------------------------------------------------- 1 | !function(a){a.on("AddEditor",function(a){a.editor.settings.inline_styles=!1}),a.PluginManager.add("legacyoutput",function(b,c,d){b.on("init",function(){var c="p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img",d=a.explode(b.settings.font_size_style_values),e=b.schema;b.formatter.register({alignleft:{selector:c,attributes:{align:"left"}},aligncenter:{selector:c,attributes:{align:"center"}},alignright:{selector:c,attributes:{align:"right"}},alignjustify:{selector:c,attributes:{align:"justify"}},bold:[{inline:"b",remove:"all"},{inline:"strong",remove:"all"},{inline:"span",styles:{fontWeight:"bold"}}],italic:[{inline:"i",remove:"all"},{inline:"em",remove:"all"},{inline:"span",styles:{fontStyle:"italic"}}],underline:[{inline:"u",remove:"all"},{inline:"span",styles:{textDecoration:"underline"},exact:!0}],strikethrough:[{inline:"strike",remove:"all"},{inline:"span",styles:{textDecoration:"line-through"},exact:!0}],fontname:{inline:"font",attributes:{face:"%value"}},fontsize:{inline:"font",attributes:{size:function(b){return a.inArray(d,b.value)+1}}},forecolor:{inline:"font",attributes:{color:"%value"}},hilitecolor:{inline:"font",styles:{backgroundColor:"%value"}}}),a.each("b,i,u,strike".split(","),function(a){e.addValidElements(a+"[*]")}),e.getElementRule("font")||e.addValidElements("font[face|size|color|style]"),a.each(c.split(","),function(a){var b=e.getElementRule(a);b&&(b.attributes.align||(b.attributes.align={},b.attributesOrder.push("align")))})}),b.addButton("fontsizeselect",function(){var a=[],c="8pt=1 10pt=2 12pt=3 14pt=4 18pt=5 24pt=6 36pt=7",d=b.settings.fontsize_formats||c;return b.$.each(d.split(" "),function(b,c){var d=c,e=c,f=c.split("=");f.length>1&&(d=f[0],e=f[1]),a.push({text:d,value:e})}),{type:"listbox",text:"Font Sizes",tooltip:"Font Sizes",values:a,fixedWidth:!0,onPostRender:function(){var a=this;b.on("NodeChange",function(){var c;c=b.dom.getParent(b.selection.getNode(),"font"),c?a.value(c.size):a.value("")})},onclick:function(a){a.control.settings.value&&b.execCommand("FontSize",!1,a.control.settings.value)}}}),b.addButton("fontselect",function(){function a(a){a=a.replace(/;$/,"").split(";");for(var b=a.length;b--;)a[b]=a[b].split("=");return a}var c="Andale Mono=andale mono,monospace;Arial=arial,helvetica,sans-serif;Arial Black=arial black,sans-serif;Book Antiqua=book antiqua,palatino,serif;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier,monospace;Georgia=georgia,palatino,serif;Helvetica=helvetica,arial,sans-serif;Impact=impact,sans-serif;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco,monospace;Times New Roman=times new roman,times,serif;Trebuchet MS=trebuchet ms,geneva,sans-serif;Verdana=verdana,geneva,sans-serif;Webdings=webdings;Wingdings=wingdings,zapf dingbats",e=[],f=a(b.settings.font_formats||c);return d.each(f,function(a,b){e.push({text:{raw:b[0]},value:b[1],textStyle:-1==b[1].indexOf("dings")?"font-family:"+b[1]:""})}),{type:"listbox",text:"Font Family",tooltip:"Font Family",values:e,fixedWidth:!0,onPostRender:function(){var a=this;b.on("NodeChange",function(){var c;c=b.dom.getParent(b.selection.getNode(),"font"),c?a.value(c.face):a.value("")})},onselect:function(a){a.control.settings.value&&b.execCommand("FontName",!1,a.control.settings.value)}}})})}(tinymce); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/link/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("link",function(a){function b(b){return function(){var c=a.settings.link_list;"string"==typeof c?tinymce.util.XHR.send({url:c,success:function(a){b(tinymce.util.JSON.parse(a))}}):"function"==typeof c?c(b):b(c)}}function c(a,b,c){function d(a,c){return c=c||[],tinymce.each(a,function(a){var e={text:a.text||a.title};a.menu?e.menu=d(a.menu):(e.value=a.value,b&&b(e)),c.push(e)}),c}return d(a,c||[])}function d(b){function d(a){var b=l.find("#text");(!b.value()||a.lastControl&&b.value()==a.lastControl.text())&&b.value(a.control.text()),l.find("#href").value(a.control.value())}function e(b){var c=[];return tinymce.each(a.dom.select("a:not([href])"),function(a){var d=a.name||a.id;d&&c.push({text:d,value:"#"+d,selected:-1!=b.indexOf("#"+d)})}),c.length?(c.unshift({text:"None",value:""}),{name:"anchor",type:"listbox",label:"Anchors",values:c,onselect:d}):void 0}function f(){!k&&0===u.text.length&&m&&this.parent().parent().find("#text")[0].value(this.value())}function g(b){var c=b.meta||{};o&&o.value(a.convertURL(this.value(),"href")),tinymce.each(b.meta,function(a,b){l.find("#"+b).value(a)}),c.text||f.call(this)}function h(a){var b=v.getContent();if(/]+>[^<]+<\/a>$/.test(b)||-1==b.indexOf("href=")))return!1;if(a){var c,d=a.childNodes;if(0===d.length)return!1;for(c=d.length-1;c>=0;c--)if(3!=d[c].nodeType)return!1}return!0}var i,j,k,l,m,n,o,p,q,r,s,t,u={},v=a.selection,w=a.dom;i=v.getNode(),j=w.getParent(i,"a[href]"),m=h(),u.text=k=j?j.innerText||j.textContent:v.getContent({format:"text"}),u.href=j?w.getAttrib(j,"href"):"",j?u.target=w.getAttrib(j,"target"):a.settings.default_link_target&&(u.target=a.settings.default_link_target),(t=w.getAttrib(j,"rel"))&&(u.rel=t),(t=w.getAttrib(j,"class"))&&(u["class"]=t),(t=w.getAttrib(j,"title"))&&(u.title=t),m&&(n={name:"text",type:"textbox",size:40,label:"Text to display",onchange:function(){u.text=this.value()}}),b&&(o={type:"listbox",label:"Link list",values:c(b,function(b){b.value=a.convertURL(b.value||b.url,"href")},[{text:"None",value:""}]),onselect:d,value:a.convertURL(u.href,"href"),onPostRender:function(){o=this}}),a.settings.target_list!==!1&&(a.settings.target_list||(a.settings.target_list=[{text:"None",value:""},{text:"New window",value:"_blank"}]),q={name:"target",type:"listbox",label:"Target",values:c(a.settings.target_list)}),a.settings.rel_list&&(p={name:"rel",type:"listbox",label:"Rel",values:c(a.settings.rel_list)}),a.settings.link_class_list&&(r={name:"class",type:"listbox",label:"Class",values:c(a.settings.link_class_list,function(b){b.value&&(b.textStyle=function(){return a.formatter.getCssText({inline:"a",classes:[b.value]})})})}),a.settings.link_title!==!1&&(s={name:"title",type:"textbox",label:"Title",value:u.title}),l=a.windowManager.open({title:"Insert link",data:u,body:[{name:"href",type:"filepicker",filetype:"file",size:40,autofocus:!0,label:"Url",onchange:g,onkeyup:f},n,s,e(u.href),o,p,q,r],onSubmit:function(b){function c(b,c){var d=a.selection.getRng();tinymce.util.Delay.setEditorTimeout(a,function(){a.windowManager.confirm(b,function(b){a.selection.setRng(d),c(b)})})}function d(){var b={href:e,target:u.target?u.target:null,rel:u.rel?u.rel:null,"class":u["class"]?u["class"]:null,title:u.title?u.title:null};j?(a.focus(),m&&u.text!=k&&("innerText"in j?j.innerText=u.text:j.textContent=u.text),w.setAttribs(j,b),v.select(j),a.undoManager.add()):m?a.insertContent(w.createHTML("a",b,w.encode(u.text))):a.execCommand("mceInsertLink",!1,b)}var e;return u=tinymce.extend(u,b.data),(e=u.href)?e.indexOf("@")>0&&-1==e.indexOf("//")&&-1==e.indexOf("mailto:")?void c("The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?",function(a){a&&(e="mailto:"+e),d()}):a.settings.link_assume_external_targets&&!/^\w+:/i.test(e)||!a.settings.link_assume_external_targets&&/^\s*www[\.|\d\.]/i.test(e)?void c("The URL you entered seems to be an external link. Do you want to add the required http:// prefix?",function(a){a&&(e="http://"+e),d()}):void d():void a.execCommand("unlink")}})}a.addButton("link",{icon:"link",tooltip:"Insert/edit link",shortcut:"Meta+K",onclick:b(d),stateSelector:"a[href]"}),a.addButton("unlink",{icon:"unlink",tooltip:"Remove link",cmd:"unlink",stateSelector:"a[href]"}),a.addShortcut("Meta+K","",b(d)),a.addCommand("mceLink",b(d)),this.showDialog=d,a.addMenuItem("link",{icon:"link",text:"Insert/edit link",shortcut:"Meta+K",onclick:b(d),stateSelector:"a[href]",context:"insert",prependToContext:!0})}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/media/moxieplayer.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/tinymce/js/tinymce/plugins/media/moxieplayer.swf -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/nonbreaking/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("nonbreaking",function(a){var b=a.getParam("nonbreaking_force_tab");if(a.addCommand("mceNonBreaking",function(){a.insertContent(a.plugins.visualchars&&a.plugins.visualchars.state?' ':" "),a.dom.setAttrib(a.dom.select("span.mce-nbsp"),"data-mce-bogus","1")}),a.addButton("nonbreaking",{title:"Nonbreaking space",cmd:"mceNonBreaking"}),a.addMenuItem("nonbreaking",{text:"Nonbreaking space",cmd:"mceNonBreaking",context:"insert"}),b){var c=+b>1?+b:3;a.on("keydown",function(b){if(9==b.keyCode){if(b.shiftKey)return;b.preventDefault();for(var d=0;c>d;d++)a.execCommand("mceNonBreaking")}})}}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/noneditable/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("noneditable",function(a){function b(a){return function(b){return-1!==(" "+b.attr("class")+" ").indexOf(a)}}function c(b){function c(b){var c=arguments,d=c[c.length-2];return d>0&&'"'==g.charAt(d-1)?b:''+a.dom.encode("string"==typeof c[1]?c[1]:c[0])+""}var d=f.length,g=b.content,h=tinymce.trim(e);if("raw"!=b.format){for(;d--;)g=g.replace(f[d],c);b.content=g}}var d,e,f,g="contenteditable";d=" "+tinymce.trim(a.getParam("noneditable_editable_class","mceEditable"))+" ",e=" "+tinymce.trim(a.getParam("noneditable_noneditable_class","mceNonEditable"))+" ";var h=b(d),i=b(e);f=a.getParam("noneditable_regexp"),f&&!f.length&&(f=[f]),a.on("PreInit",function(){f&&a.on("BeforeSetContent",c),a.parser.addAttributeFilter("class",function(a){for(var b,c=a.length;c--;)b=a[c],h(b)?b.attr(g,"true"):i(b)&&b.attr(g,"false")}),a.serializer.addAttributeFilter(g,function(a){for(var b,c=a.length;c--;)b=a[c],(h(b)||i(b))&&(f&&b.attr("data-mce-content")?(b.name="#text",b.type=3,b.raw=!0,b.value=b.attr("data-mce-content")):b.attr(g,null))})})}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/pagebreak/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("pagebreak",function(a){var b="mce-pagebreak",c=a.getParam("pagebreak_separator",""),d=new RegExp(c.replace(/[\?\.\*\[\]\(\)\{\}\+\^\$\:]/g,function(a){return"\\"+a}),"gi"),e='';a.addCommand("mcePageBreak",function(){a.settings.pagebreak_split_block?a.insertContent("

"+e+"

"):a.insertContent(e)}),a.addButton("pagebreak",{title:"Page break",cmd:"mcePageBreak"}),a.addMenuItem("pagebreak",{text:"Page break",icon:"pagebreak",cmd:"mcePageBreak",context:"insert"}),a.on("ResolveName",function(c){"IMG"==c.target.nodeName&&a.dom.hasClass(c.target,b)&&(c.name="pagebreak")}),a.on("click",function(c){c=c.target,"IMG"===c.nodeName&&a.dom.hasClass(c,b)&&a.selection.select(c)}),a.on("BeforeSetContent",function(a){a.content=a.content.replace(d,e)}),a.on("PreInit",function(){a.serializer.addNodeFilter("img",function(b){for(var d,e,f=b.length;f--;)if(d=b[f],e=d.attr("class"),e&&-1!==e.indexOf("mce-pagebreak")){var g=d.parent;if(a.schema.getBlockElements()[g.name]&&a.settings.pagebreak_split_block){g.type=3,g.value=c,g.raw=!0,d.remove();continue}d.type=3,d.value=c,d.raw=!0}})})}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/preview/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("preview",function(a){var b=a.settings,c=!tinymce.Env.ie;a.addCommand("mcePreview",function(){a.windowManager.open({title:"Preview",width:parseInt(a.getParam("plugin_preview_width","650"),10),height:parseInt(a.getParam("plugin_preview_height","500"),10),html:'",buttons:{text:"Close",onclick:function(){this.parent().parent().close()}},onPostRender:function(){var d,e="";e+='',tinymce.each(a.contentCSS,function(b){e+=''});var f=b.body_id||"tinymce";-1!=f.indexOf("=")&&(f=a.getParam("body_id","","hash"),f=f[a.id]||f);var g=b.body_class||"";-1!=g.indexOf("=")&&(g=a.getParam("body_class","","hash"),g=g[a.id]||"");var h=a.settings.directionality?' dir="'+a.settings.directionality+'"':"";if(d=""+e+'"+a.getContent()+"",c)this.getEl("body").firstChild.src="data:text/html;charset=utf-8,"+encodeURIComponent(d);else{var i=this.getEl("body").firstChild.contentWindow.document;i.open(),i.write(d),i.close()}}})}),a.addButton("preview",{title:"Preview",cmd:"mcePreview"}),a.addMenuItem("preview",{text:"Preview",cmd:"mcePreview",context:"view"})}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/print/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("print",function(a){a.addCommand("mcePrint",function(){a.getWin().print()}),a.addButton("print",{title:"Print",cmd:"mcePrint"}),a.addShortcut("Meta+P","","mcePrint"),a.addMenuItem("print",{text:"Print",cmd:"mcePrint",icon:"print",shortcut:"Meta+P",context:"file"})}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/save/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("save",function(a){function b(){var b;return b=tinymce.DOM.getParent(a.id,"form"),!a.getParam("save_enablewhendirty",!0)||a.isDirty()?(tinymce.triggerSave(),a.getParam("save_onsavecallback")?(a.execCallback("save_onsavecallback",a),void a.nodeChanged()):void(b?(a.setDirty(!1),(!b.onsubmit||b.onsubmit())&&("function"==typeof b.submit?b.submit():c(a.translate("Error: Form submit field collision."))),a.nodeChanged()):c(a.translate("Error: No form element found.")))):void 0}function c(b){a.notificationManager.open({text:b,type:"error"})}function d(){var b=tinymce.trim(a.startContent);return a.getParam("save_oncancelcallback")?void a.execCallback("save_oncancelcallback",a):(a.setContent(b),a.undoManager.clear(),void a.nodeChanged())}function e(){var b=this;a.on("nodeChange dirty",function(){b.disabled(a.getParam("save_enablewhendirty",!0)&&!a.isDirty())})}a.addCommand("mceSave",b),a.addCommand("mceCancel",d),a.addButton("save",{icon:"save",text:"Save",cmd:"mceSave",disabled:!0,onPostRender:e}),a.addButton("cancel",{text:"Cancel",icon:!1,cmd:"mceCancel",disabled:!0,onPostRender:e}),a.addShortcut("Meta+S","","mceSave")}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/searchreplace/plugin.min.js: -------------------------------------------------------------------------------- 1 | !function(){function a(a){return a&&1==a.nodeType&&"false"===a.contentEditable}function b(b,c,d,e,f){function g(a,b){if(b=b||0,!a[0])throw"findAndReplaceDOMText cannot handle zero-length matches";var c=a.index;if(b>0){var d=a[b];if(!d)throw"Invalid capture group";c+=a[0].indexOf(d),a[0]=d}return[c,c+a[0].length,[a[0]]]}function h(b){var c;if(3===b.nodeType)return b.data;if(o[b.nodeName]&&!n[b.nodeName])return"";if(c="",a(b))return"\n";if((n[b.nodeName]||p[b.nodeName])&&(c+="\n"),b=b.firstChild)do c+=h(b);while(b=b.nextSibling);return c}function i(b,c,d){var e,f,g,h,i=[],j=0,k=b,l=c.shift(),m=0;a:for(;;){if((n[k.nodeName]||p[k.nodeName]||a(k))&&j++,3===k.nodeType&&(!f&&k.length+j>=l[1]?(f=k,h=l[1]-j):e&&i.push(k),!e&&k.length+j>l[0]&&(e=k,g=l[0]-j),j+=k.length),e&&f){if(k=d({startNode:e,startNodeIndex:g,endNode:f,endNodeIndex:h,innerNodes:i,match:l[2],matchIndex:m}),j-=f.length-h,e=null,f=null,i=[],l=c.shift(),m++,!l)break}else if(o[k.nodeName]&&!n[k.nodeName]||!k.firstChild){if(k.nextSibling){k=k.nextSibling;continue}}else if(!a(k)){k=k.firstChild;continue}for(;;){if(k.nextSibling){k=k.nextSibling;break}if(k.parentNode===b)break a;k=k.parentNode}}}function j(a){var b;if("function"!=typeof a){var c=a.nodeType?a:m.createElement(a);b=function(a,b){var d=c.cloneNode(!1);return d.setAttribute("data-mce-index",b),a&&d.appendChild(m.createTextNode(a)),d}}else b=a;return function(a){var c,d,e,f=a.startNode,g=a.endNode,h=a.matchIndex;if(f===g){var i=f;e=i.parentNode,a.startNodeIndex>0&&(c=m.createTextNode(i.data.substring(0,a.startNodeIndex)),e.insertBefore(c,i));var j=b(a.match[0],h);return e.insertBefore(j,i),a.endNodeIndexn;++n){var p=a.innerNodes[n],q=b(p.data,h);p.parentNode.replaceChild(q,p),l.push(q)}var r=b(g.data.substring(0,a.endNodeIndex),h);return e=f.parentNode,e.insertBefore(c,f),e.insertBefore(k,f),e.removeChild(f),e=g.parentNode,e.insertBefore(r,g),e.insertBefore(d,g),e.removeChild(g),r}}var k,l,m,n,o,p,q=[],r=0;if(m=c.ownerDocument,n=f.getBlockElements(),o=f.getWhiteSpaceElements(),p=f.getShortEndedElements(),l=h(c)){if(b.global)for(;k=b.exec(l);)q.push(g(k,e));else k=l.match(b),q.push(g(k,e));return q.length&&(r=q.length,i(c,q,j(d))),r}}function c(a){function c(){function b(){f.statusbar.find("#next").disabled(!g(l+1).length),f.statusbar.find("#prev").disabled(!g(l-1).length)}function c(){a.windowManager.alert("Could not find the specified string.",function(){f.find("#find")[0].focus()})}var d,e={};d=tinymce.trim(a.selection.getContent({format:"text"}));var f=a.windowManager.open({layout:"flex",pack:"center",align:"center",onClose:function(){a.focus(),k.done()},onSubmit:function(a){var d,h,i,j;return a.preventDefault(),h=f.find("#case").checked(),j=f.find("#words").checked(),i=f.find("#find").value(),i.length?e.text==i&&e.caseState==h&&e.wholeWord==j?0===g(l+1).length?void c():(k.next(),void b()):(d=k.find(i,h,j),d||c(),f.statusbar.items().slice(1).disabled(0===d),b(),void(e={text:i,caseState:h,wholeWord:j})):(k.done(!1),void f.statusbar.items().slice(1).disabled(!0))},buttons:[{text:"Find",subtype:"primary",onclick:function(){f.submit()}},{text:"Replace",disabled:!0,onclick:function(){k.replace(f.find("#replace").value())||(f.statusbar.items().slice(1).disabled(!0),l=-1,e={})}},{text:"Replace all",disabled:!0,onclick:function(){k.replace(f.find("#replace").value(),!0,!0),f.statusbar.items().slice(1).disabled(!0),e={}}},{type:"spacer",flex:1},{text:"Prev",name:"prev",disabled:!0,onclick:function(){k.prev(),b()}},{text:"Next",name:"next",disabled:!0,onclick:function(){k.next(),b()}}],title:"Find and replace",items:{type:"form",padding:20,labelGap:30,spacing:10,items:[{type:"textbox",name:"find",size:40,label:"Find",value:d},{type:"textbox",name:"replace",size:40,label:"Replace with"},{type:"checkbox",name:"case",text:"Match case",label:" "},{type:"checkbox",name:"words",text:"Whole words",label:" "}]}})}function d(a){var b=a.getAttribute("data-mce-index");return"number"==typeof b?""+b:b}function e(c){var d,e;return e=a.dom.create("span",{"data-mce-bogus":1}),e.className="mce-match-marker",d=a.getBody(),k.done(!1),b(c,d,e,!1,a.schema)}function f(a){var b=a.parentNode;a.firstChild&&b.insertBefore(a.firstChild,a),a.parentNode.removeChild(a)}function g(b){var c,e=[];if(c=tinymce.toArray(a.getBody().getElementsByTagName("span")),c.length)for(var f=0;f0}var k=this,l=-1;k.init=function(a){a.addMenuItem("searchreplace",{text:"Find and replace",shortcut:"Meta+F",onclick:c,separator:"before",context:"edit"}),a.addButton("searchreplace",{tooltip:"Find and replace",shortcut:"Meta+F",onclick:c}),a.addCommand("SearchReplace",c),a.shortcuts.add("Meta+F","",c)},k.find=function(a,b,c){a=a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&"),a=c?"\\b"+a+"\\b":a;var d=e(new RegExp(a,b?"g":"gi"));return d&&(l=-1,l=h(!0)),d},k.next=function(){var a=h(!0);-1!==a&&(l=a)},k.prev=function(){var a=h(!1);-1!==a&&(l=a)},k.replace=function(b,c,e){var h,m,n,o,p,q,r=l;for(c=c!==!1,n=a.getBody(),m=tinymce.grep(tinymce.toArray(n.getElementsByTagName("span")),j),h=0;hl&&m[h].setAttribute("data-mce-index",p-1)}return a.undoManager.add(),l=r,c?(q=g(r+1).length>0,k.next()):(q=g(r-1).length>0,k.prev()),!e&&q},k.done=function(b){var c,e,g,h;for(e=tinymce.toArray(a.getBody().getElementsByTagName("span")),c=0;c0){for(j=g+1;j=0;j--)if(i(h[j]))return h[j];return null}var g,h,i,j;if(!(9!==b.keyCode||b.ctrlKey||b.altKey||b.metaKey||b.isDefaultPrevented())&&(i=f(a.getParam("tab_focus",a.getParam("tabfocus_elements",":prev,:next"))),1==i.length&&(i[1]=i[0],i[0]=":prev"),h=b.shiftKey?":prev"==i[0]?c(-1):d.get(i[0]):":next"==i[1]?c(1):d.get(i[1]))){var k=tinymce.get(h.id||h.name);h.id&&k?k.focus():tinymce.util.Delay.setTimeout(function(){tinymce.Env.webkit||window.focus(),h.focus()},10),b.preventDefault()}}var d=tinymce.DOM,e=tinymce.each,f=tinymce.explode;a.on("init",function(){a.inline&&tinymce.DOM.setAttrib(a.getBody(),"tabIndex",null),a.on("keyup",b),tinymce.Env.gecko?a.on("keypress keydown",c):a.on("keydown",c)})}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/template/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("template",function(a){function b(b){return function(){var c=a.settings.templates;return"function"==typeof c?void c(b):void("string"==typeof c?tinymce.util.XHR.send({url:c,success:function(a){b(tinymce.util.JSON.parse(a))}}):b(c))}}function c(b){function c(b){function c(b){if(-1==b.indexOf("")){var c="";tinymce.each(a.contentCSS,function(b){c+=''}),b=""+c+""+b+""}b=f(b,"template_preview_replace_values");var e=d.find("iframe")[0].getEl().contentWindow.document;e.open(),e.write(b),e.close()}var g=b.control.value();g.url?tinymce.util.XHR.send({url:g.url,success:function(a){e=a,c(e)}}):(e=g.content,c(e)),d.find("#description")[0].text(b.control.value().description)}var d,e,h=[];if(!b||0===b.length){var i=a.translate("No templates defined.");return void a.notificationManager.open({text:i,type:"info"})}tinymce.each(b,function(a){h.push({selected:!h.length,text:a.title,value:{url:a.url,content:a.content,description:a.description}})}),d=a.windowManager.open({title:"Insert template",layout:"flex",direction:"column",align:"stretch",padding:15,spacing:10,items:[{type:"form",flex:0,padding:0,items:[{type:"container",label:"Templates",items:{type:"listbox",label:"Templates",name:"template",values:h,onselect:c}}]},{type:"label",name:"description",label:"Description",text:"\xa0"},{type:"iframe",flex:1,border:1}],onsubmit:function(){g(!1,e)},width:a.getParam("template_popup_width",600),height:a.getParam("template_popup_height",500)}),d.find("listbox")[0].fire("select")}function d(b,c){function d(a,b){if(a=""+a,a.length0&&(i=k.create("div",null),i.appendChild(j[0].cloneNode(!0))),h(k.select("*",i),function(b){g(b,a.getParam("template_cdate_classes","cdate").replace(/\s+/g,"|"))&&(b.innerHTML=d(a.getParam("template_cdate_format",a.getLang("template.cdate_format")))),g(b,a.getParam("template_mdate_classes","mdate").replace(/\s+/g,"|"))&&(b.innerHTML=d(a.getParam("template_mdate_format",a.getLang("template.mdate_format")))),g(b,a.getParam("template_selected_content_classes","selcontent").replace(/\s+/g,"|"))&&(b.innerHTML=l)}),e(i),a.execCommand("mceInsertContent",!1,i.innerHTML),a.addVisual()}var h=tinymce.each;a.addCommand("mceInsertTemplate",g),a.addButton("template",{title:"Insert template",onclick:b(c)}),a.addMenuItem("template",{text:"Insert template",onclick:b(c),context:"insert"}),a.on("PreProcess",function(b){var c=a.dom;h(c.select("div",b.node),function(b){c.hasClass(b,"mceTmpl")&&(h(c.select("*",b),function(b){c.hasClass(b,a.getParam("template_mdate_classes","mdate").replace(/\s+/g,"|"))&&(b.innerHTML=d(a.getParam("template_mdate_format",a.getLang("template.mdate_format"))))}),e(b))})})}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/textcolor/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("textcolor",function(a){function b(b){var c;return a.dom.getParents(a.selection.getStart(),function(a){var d;(d=a.style["forecolor"==b?"color":"background-color"])&&(c=d)}),c}function c(){var b,c,d=[];for(c=a.settings.textcolor_map||["000000","Black","993300","Burnt orange","333300","Dark olive","003300","Dark green","003366","Dark azure","000080","Navy Blue","333399","Indigo","333333","Very dark gray","800000","Maroon","FF6600","Orange","808000","Olive","008000","Green","008080","Teal","0000FF","Blue","666699","Grayish blue","808080","Gray","FF0000","Red","FF9900","Amber","99CC00","Yellow green","339966","Sea green","33CCCC","Turquoise","3366FF","Royal blue","800080","Purple","999999","Medium gray","FF00FF","Magenta","FFCC00","Gold","FFFF00","Yellow","00FF00","Lime","00FFFF","Aqua","00CCFF","Sky blue","993366","Red violet","FFFFFF","White","FF99CC","Pink","FFCC99","Peach","FFFF99","Light yellow","CCFFCC","Pale green","CCFFFF","Pale cyan","99CCFF","Light sky blue","CC99FF","Plum"],b=0;b
'+(c?"×":"")+"
"}var d,e,f,g,h,k,l,m=this,n=m._id,o=0;for(d=c(),d.push({text:tinymce.translate("No color"),color:"transparent"}),f='',g=d.length-1,k=0;j>k;k++){for(f+="",h=0;i>h;h++)l=k*i+h,l>g?f+="":(e=d[l],f+=b(e.color,e.text));f+=""}if(a.settings.color_picker_callback){for(f+='",f+="",h=0;i>h;h++)f+=b("","Custom color");f+=""}return f+="
"}function e(b,c){a.undoManager.transact(function(){a.focus(),a.formatter.apply(b,{value:c}),a.nodeChanged()})}function f(b){a.undoManager.transact(function(){a.focus(),a.formatter.remove(b,{value:null},null,!0),a.nodeChanged()})}function g(c){function d(a){k.hidePanel(),k.color(a),e(k.settings.format,a)}function g(){k.hidePanel(),k.resetColor(),f(k.settings.format)}function h(a,b){a.style.background=b,a.setAttribute("data-mce-color",b)}var j,k=this.parent();tinymce.DOM.getParent(c.target,".mce-custom-color-btn")&&(k.hidePanel(),a.settings.color_picker_callback.call(a,function(a){var b,c,e,f=k.panel.getEl().getElementsByTagName("table")[0];for(b=tinymce.map(f.rows[f.rows.length-1].childNodes,function(a){return a.firstChild}),e=0;ee;e++)h(b[e],b[e+1].getAttribute("data-mce-color"));h(c,a),d(a)},b(k.settings.format))),j=c.target.getAttribute("data-mce-color"),j?(this.lastId&&document.getElementById(this.lastId).setAttribute("aria-selected",!1),c.target.setAttribute("aria-selected",!0),this.lastId=c.target.id,"transparent"==j?g():d(j)):null!==j&&k.hidePanel()}function h(){var a=this;a._color?e(a.settings.format,a._color):f(a.settings.format)}var i,j;j=a.settings.textcolor_rows||5,i=a.settings.textcolor_cols||8,a.addButton("forecolor",{type:"colorbutton",tooltip:"Text color",format:"forecolor",panel:{role:"application",ariaRemember:!0,html:d,onclick:g},onclick:h}),a.addButton("backcolor",{type:"colorbutton",tooltip:"Background color",format:"hilitecolor",panel:{role:"application",ariaRemember:!0,html:d,onclick:g},onclick:h})}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/textpattern/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("textpattern",function(a){function b(){return j&&(i.sort(function(a,b){return a.start.length>b.start.length?-1:a.start.length'+a+"
"}function f(){var a,b="";for(a in n)b+=a;return new RegExp("["+b+"]","g")}function g(){var a,b="";for(a in n)b&&(b+=","),b+="span.mce-"+n[a];return b}var h,i,j,k,l,m,n,o,p=a.getBody(),q=a.selection;if(n={"\xa0":"nbsp","\xad":"shy"},d=!d,e.state=d,a.fire("VisualChars",{state:d}),o=f(),b&&(m=q.getBookmark()),d)for(i=[],tinymce.walk(p,function(a){3==a.nodeType&&a.nodeValue&&o.test(a.nodeValue)&&i.push(a)},"childNodes"),j=0;j=0;j--)a.dom.remove(i[j],1);q.moveToBookmark(m)}function c(){var b=this;a.on("VisualChars",function(a){b.active(a.state)})}var d,e=this;a.addCommand("mceVisualChars",b),a.addButton("visualchars",{title:"Show invisible characters",cmd:"mceVisualChars",onPostRender:c}),a.addMenuItem("visualchars",{text:"Show invisible characters",cmd:"mceVisualChars",onPostRender:c,selectable:!0,context:"view",prependToContext:!0}),a.on("beforegetcontent",function(a){d&&"raw"!=a.format&&!a.draft&&(d=!0,b(!1))})}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/plugins/wordcount/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("wordcount",function(a){function b(){a.theme.panel.find("#wordcount").text(["Words: {0}",e.getCount()])}var c,d,e=this;c=a.getParam("wordcount_countregex",/[\w\u2019\x27\-\u00C0-\u1FFF]+/g),d=a.getParam("wordcount_cleanregex",/[0-9.(),;:!?%#$?\x27\x22_+=\\\/\-]*/g),a.on("init",function(){var c=a.theme.panel&&a.theme.panel.find("#statusbar")[0];c&&tinymce.util.Delay.setEditorTimeout(a,function(){c.insert({type:"label",name:"wordcount",text:["Words: {0}",e.getCount()],classes:"wordcount",disabled:a.settings.readonly},0),a.on("setcontent beforeaddundo",b),a.on("keyup",function(a){32==a.keyCode&&b()})},0)}),e.getCount=function(){var b=a.getContent({format:"raw"}),e=0;if(b){b=b.replace(/\.\.\./g," "),b=b.replace(/<.[^<>]*?>/g," ").replace(/ | /gi," "),b=b.replace(/(\w+)(&#?[a-z0-9]+;)+(\w+)/i,"$1$3").replace(/&.+?;/g," "),b=b.replace(d,"");var f=b.match(c);f&&(e=f.length)}return e}}); -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/lightgray/content.inline.min.css: -------------------------------------------------------------------------------- 1 | .mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:black;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:normal;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3a3a3a;background:#d5d5d5 url(img/object.gif) no-repeat center}.mce-preview-object{display:inline-block;position:relative;margin:0 2px 0 2px;line-height:0;border:1px solid gray}.mce-preview-object .mce-shim{position:absolute;top:0;left:0;width:100%;height:100%;background:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}figure.align-left{float:left}figure.align-right{float:right}figure.image.align-center{display:table;margin-left:auto;margin-right:auto}figure.image{display:inline-block;border:1px solid gray;margin:0 2px 0 1px;background:#f5f2f0}figure.image img{margin:8px 8px 0 8px}figure.image figcaption{margin:6px 8px 6px 8px;text-align:center}.mce-preview-object[data-mce-selected] .mce-shim{display:none}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3a3a3a;background:#d5d5d5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#aaa}.mce-shy::after{content:'-'}hr{cursor:default}.mce-match-marker{background:#aaa;color:#fff}.mce-match-marker-selected{background:#39f;color:#fff}.mce-spellchecker-word{border-bottom:2px solid #f00;cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #bbb}td[data-mce-selected],th[data-mce-selected]{background-color:#39f !important}.mce-edit-focus{outline:1px dotted #333}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2d8ac7}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #7acaff}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2d8ac7}.mce-resize-bar-dragging{background-color:blue;opacity:.25;filter:alpha(opacity=25);zoom:1} -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/lightgray/content.min.css: -------------------------------------------------------------------------------- 1 | body{background-color:#fff;color:#000;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:11px;scrollbar-3dlight-color:#f0f0ee;scrollbar-arrow-color:#676662;scrollbar-base-color:#f0f0ee;scrollbar-darkshadow-color:#ddd;scrollbar-face-color:#e0e0dd;scrollbar-highlight-color:#f0f0ee;scrollbar-shadow-color:#f0f0ee;scrollbar-track-color:#f5f5f5}td,th{font-family:Verdana,Arial,Helvetica,sans-serif;font-size:11px}.mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:black;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:normal;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3a3a3a;background:#d5d5d5 url(img/object.gif) no-repeat center}.mce-preview-object{display:inline-block;position:relative;margin:0 2px 0 2px;line-height:0;border:1px solid gray}.mce-preview-object .mce-shim{position:absolute;top:0;left:0;width:100%;height:100%;background:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}figure.align-left{float:left}figure.align-right{float:right}figure.image.align-center{display:table;margin-left:auto;margin-right:auto}figure.image{display:inline-block;border:1px solid gray;margin:0 2px 0 1px;background:#f5f2f0}figure.image img{margin:8px 8px 0 8px}figure.image figcaption{margin:6px 8px 6px 8px;text-align:center}.mce-preview-object[data-mce-selected] .mce-shim{display:none}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3a3a3a;background:#d5d5d5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#aaa}.mce-shy::after{content:'-'}hr{cursor:default}.mce-match-marker{background:#aaa;color:#fff}.mce-match-marker-selected{background:#39f;color:#fff}.mce-spellchecker-word{border-bottom:2px solid #f00;cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #bbb}td[data-mce-selected],th[data-mce-selected]{background-color:#39f !important}.mce-edit-focus{outline:1px dotted #333}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2d8ac7}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #7acaff}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2d8ac7}.mce-resize-bar-dragging{background-color:blue;opacity:.25;filter:alpha(opacity=25);zoom:1} -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/lightgray/fonts/tinymce-small.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/tinymce/js/tinymce/skins/lightgray/fonts/tinymce-small.eot -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/lightgray/fonts/tinymce-small.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/tinymce/js/tinymce/skins/lightgray/fonts/tinymce-small.ttf -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/lightgray/fonts/tinymce-small.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/tinymce/js/tinymce/skins/lightgray/fonts/tinymce-small.woff -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/lightgray/fonts/tinymce.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/tinymce/js/tinymce/skins/lightgray/fonts/tinymce.eot -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/lightgray/fonts/tinymce.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/tinymce/js/tinymce/skins/lightgray/fonts/tinymce.ttf -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/lightgray/fonts/tinymce.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/tinymce/js/tinymce/skins/lightgray/fonts/tinymce.woff -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/lightgray/img/anchor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/tinymce/js/tinymce/skins/lightgray/img/anchor.gif -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/lightgray/img/loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/tinymce/js/tinymce/skins/lightgray/img/loader.gif -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/lightgray/img/object.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/tinymce/js/tinymce/skins/lightgray/img/object.gif -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/lightgray/img/trans.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/tinymce/js/tinymce/skins/lightgray/img/trans.gif -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/myskin/content.inline.min.css: -------------------------------------------------------------------------------- 1 | .mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:black;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:normal;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3a3a3a;background:#d5d5d5 url(img/object.gif) no-repeat center}.mce-preview-object{display:inline-block;position:relative;margin:0 2px 0 2px;line-height:0;border:1px solid gray}.mce-preview-object .mce-shim{position:absolute;top:0;left:0;width:100%;height:100%;background:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}figure.align-left{float:left}figure.align-right{float:right}figure.image.align-center{display:table;margin-left:auto;margin-right:auto}figure.image{display:inline-block;border:1px solid gray;margin:0 2px 0 1px;background:#f5f2f0}figure.image img{margin:8px 8px 0 8px}figure.image figcaption{margin:6px 8px 6px 8px;text-align:center}.mce-preview-object[data-mce-selected] .mce-shim{display:none}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3a3a3a;background:#d5d5d5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#aaa}.mce-shy::after{content:'-'}hr{cursor:default}.mce-match-marker{background:#aaa;color:#fff}.mce-match-marker-selected{background:#39f;color:#fff}.mce-spellchecker-word{border-bottom:2px solid #f00;cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #bbb}td[data-mce-selected],th[data-mce-selected]{background-color:#39f !important}.mce-edit-focus{outline:1px dotted #333}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2d8ac7}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #7acaff}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2d8ac7}.mce-resize-bar-dragging{background-color:blue;opacity:.25;filter:alpha(opacity=25);zoom:1} -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/myskin/content.min.css: -------------------------------------------------------------------------------- 1 | .mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:black;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:normal;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3a3a3a;background:#d5d5d5 url(img/object.gif) no-repeat center}.mce-preview-object{display:inline-block;position:relative;margin:0 2px 0 2px;line-height:0;border:1px solid gray}.mce-preview-object .mce-shim{position:absolute;top:0;left:0;width:100%;height:100%;background:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}figure.align-left{float:left}figure.align-right{float:right}figure.image.align-center{display:table;margin-left:auto;margin-right:auto}figure.image{display:inline-block;border:1px solid gray;margin:0 2px 0 1px;background:#f5f2f0}figure.image img{margin:8px 8px 0 8px}figure.image figcaption{margin:6px 8px 6px 8px;text-align:center}.mce-preview-object[data-mce-selected] .mce-shim{display:none}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3a3a3a;background:#d5d5d5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#aaa}.mce-shy::after{content:'-'}hr{cursor:default}.mce-match-marker{background:#aaa;color:#fff}.mce-match-marker-selected{background:#39f;color:#fff}.mce-spellchecker-word{border-bottom:2px solid #f00;cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #bbb}td[data-mce-selected],th[data-mce-selected]{background-color:#39f !important}.mce-edit-focus{outline:1px dotted #333}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2d8ac7}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #7acaff}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2d8ac7}.mce-resize-bar-dragging{background-color:blue;opacity:.25;filter:alpha(opacity=25);zoom:1} -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/myskin/fonts/readme.md: -------------------------------------------------------------------------------- 1 | Icons are generated and provided by the http://icomoon.io service. 2 | -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/myskin/fonts/tinymce-small.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/tinymce/js/tinymce/skins/myskin/fonts/tinymce-small.eot -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/myskin/fonts/tinymce-small.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/tinymce/js/tinymce/skins/myskin/fonts/tinymce-small.ttf -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/myskin/fonts/tinymce-small.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/tinymce/js/tinymce/skins/myskin/fonts/tinymce-small.woff -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/myskin/fonts/tinymce.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/tinymce/js/tinymce/skins/myskin/fonts/tinymce.eot -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/myskin/fonts/tinymce.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/tinymce/js/tinymce/skins/myskin/fonts/tinymce.ttf -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/myskin/fonts/tinymce.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/tinymce/js/tinymce/skins/myskin/fonts/tinymce.woff -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/myskin/img/anchor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/tinymce/js/tinymce/skins/myskin/img/anchor.gif -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/myskin/img/loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/tinymce/js/tinymce/skins/myskin/img/loader.gif -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/myskin/img/object.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/tinymce/js/tinymce/skins/myskin/img/object.gif -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/myskin/img/trans.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/app/static/tinymce/js/tinymce/skins/myskin/img/trans.gif -------------------------------------------------------------------------------- /app/static/tinymce/js/tinymce/skins/myskin/skin.json: -------------------------------------------------------------------------------- 1 | { 2 | "skin-name": "myskin", 3 | "preview-bg": "#666666", 4 | "text": "#b5b9bf", 5 | "text-inverse": "#000000", 6 | "text-disabled": "#6e737a", 7 | "has-gradients": true, 8 | "has-radius": true, 9 | "has-boxshadow": true, 10 | "has-button-borders": true, 11 | "btn-text": "#b5b9bf", 12 | "btn-text-shadow": "#000000", 13 | "btn-bg": "#515c67", 14 | "btn-bg-hlight": "#454f59", 15 | "btn-border-top": "rgba(32,42,51,1)", 16 | "btn-border-right": "rgba(32,42,51,1)", 17 | "btn-border-bottom": "rgba(32,42,51,1)", 18 | "btn-border-left": "rgba(32,42,51,1)", 19 | "btn-split-border": "#202a33", 20 | "btn-primary-text": "#ffffff", 21 | "btn-primary-text-shadow": "#333333", 22 | "btn-primary-bg": "#006fa6", 23 | "btn-primary-bg-hlight": "#005580", 24 | "btn-padding": "4px 10px", 25 | "menu-bg": "#2f3740", 26 | "menu-border": "#202a33", 27 | "menuitem-text": "#dddddd", 28 | "menuitem-bg-selected": "#006fa6", 29 | "menuitem-bg-selected-hlight": "#005580", 30 | "menuitem-separator-top": "#25313f", 31 | "menuitem-separator-bottom": "#424f5f", 32 | "menuitem-text-inverse": "#ffffff", 33 | "menuitem-bg-active": "#0085c7", 34 | "menuitem-text-active": "#ffffff", 35 | "menuitem-preview-border-active": "#08608c", 36 | "menubar-menubtn-text": "#b5b9bf", 37 | "checkbox-border": "#202a33", 38 | "checkbox-border-focus": "#1e7dad", 39 | "panel-border": "#232b33", 40 | "panel-bg": "#404952", 41 | "panel-bg-hlight": "#404952", 42 | "textbox-bg": "#515c67", 43 | "textbox-border": "#202a33", 44 | "textbox-border-focus": "#1e7dad", 45 | "window-bg": "#404952", 46 | "window-border": "#9e9e9e", 47 | "tab-bg": "#303942", 48 | "tab-bg-hover": "#404952", 49 | "tab-bg-active": "#404952", 50 | "tab-border": "#202a33", 51 | "tabs-bg": "#303942", 52 | "notification-bg": "#f0f0f0", 53 | "notification-border": "#cccccc", 54 | "notification-text": "#333333", 55 | "notification-success-bg": "#dff0d8", 56 | "notification-success-border": "#d6e9c6", 57 | "notification-success-text": "#3c763d", 58 | "notification-info-bg": "#d9edf7", 59 | "notification-info-border": "#779ecb", 60 | "notification-info-text": "#31708f", 61 | "notification-warning-bg": "#fcf8e3", 62 | "notification-warning-border": "#faebcc", 63 | "notification-warning-text": "#8a6d3b", 64 | "notification-error-bg": "#f2dede", 65 | "notification-error-border": "#ebccd1", 66 | "notification-error-text": "#a94442", 67 | "progress-bar-bg": "#515c67", 68 | "progress-bar-bg-hlight": "#515c67", 69 | "progress-border": "#202a33", 70 | "progress-text": "#c4c4c4", 71 | "progress-text-shadow": "#000000", 72 | "slider-bg": "#515c67", 73 | "slider-border": "#202a33", 74 | "slider-handle-bg": "#454f59", 75 | "slider-handle-border": "#000000", 76 | "colorbtn-backcolor-bg": "#384552", 77 | "grid-border": "#d6d6d6", 78 | "grid-border-active": "#d6d6d6" 79 | } -------------------------------------------------------------------------------- /app/templates/403.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Blog_mini -禁止访问{% endblock %} 4 | 5 | {% block content %} 6 | 9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /app/templates/404.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Blog_mini -无法找到该页面{% endblock %} 4 | 5 | {% block content %} 6 | 9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /app/templates/500.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Blog_mini -服务器内部问题{% endblock %} 4 | 5 | {% block content %} 6 | 9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /app/templates/_article_comments.html: -------------------------------------------------------------------------------- 1 |
    2 | {% if comments %} 3 | {% for comment in comments %} 4 |
  • 5 | {% if comment.comment_type == 'reply' %} 6 |

    7 | 8 | 回复给 9 | {% if comment.followed_name() %} 10 | {{ comment.followed_name() }} 11 | {% else %} 12 | {{ comment.reply_to }} 13 | ({{ comment.reply_to }}的该条评论已经被删除!) 14 | {% endif %} 15 | : 16 |

    17 | {% endif %} 18 |
    19 | 20 |
    21 |
    22 |
    {{ moment(comment.timestamp.replace(microsecond=0)).format('LLL') }}
    23 |
    24 | {{ comment.author_name }} 25 | {% if User.query.filter_by(email=comment.author_email).count() %} 26 | 管理员 27 | {% endif %} 28 |
    29 |
    30 | {% if comment.disabled == False or current_user.is_authenticated %} 31 |

    {{ comment.content }}

    32 | {% endif %} 33 | {% if comment.disabled == True and current_user.is_authenticated %} 34 |

    35 | 36 | 该评论已经被管理员屏蔽!访客无法查看和回复此评论内容。 37 |

    38 | {% elif comment.disabled == True %} 39 |

    40 | 41 | 该评论已经被管理员屏蔽! 42 |

    43 | {% endif %} 44 |
    45 |
    46 |
    47 | {% if current_user.is_authenticated %} 48 |
    49 | {% if comment.disabled == False %} 50 | 52 | 屏蔽 53 | 54 | {% else %} 55 | 57 | 恢复 58 | 59 | {% endif %} 60 |
    61 |
    62 | 66 |
    67 | {% endif %} 68 | {% if comment.disabled == False or current_user.is_authenticated %} 69 |
    70 | 73 |
    74 | {% endif %} 75 |
    76 |
  • 77 | {% endfor %} 78 | {% else %} 79 |
  • 80 |
    暂无评论
    81 |
  • 82 | {% endif %} 83 |
84 | 85 | 86 | 109 | -------------------------------------------------------------------------------- /app/templates/_article_entry.html: -------------------------------------------------------------------------------- 1 | {% for article in articles %} 2 |
3 | {% include '_article_info.html' %} 4 |
5 | {% endfor %} 6 | -------------------------------------------------------------------------------- /app/templates/_article_info.html: -------------------------------------------------------------------------------- 1 |
2 |

3 | {{ article.title }} 4 |

5 |
6 | 25 |
26 |

{{ article.summary }}

27 |
-------------------------------------------------------------------------------- /app/templates/_macros.html: -------------------------------------------------------------------------------- 1 | {% macro pagination_widget(pagination, endpoint, fragment='') %} 2 |
    3 | 4 | 6 | « 7 | 8 | 9 | {% for p in pagination.iter_pages() %} 10 | {% if p %} 11 | {% if p == pagination.page %} 12 |
  • 13 | {{ p }} 14 |
  • 15 | {% else %} 16 |
  • 17 | {{ p }} 18 |
  • 19 | {% endif %} 20 | {% else %} 21 |
  • 22 | {% endif %} 23 | {% endfor %} 24 | 25 | 27 | » 28 | 29 | 30 |
31 | {% endmacro %} -------------------------------------------------------------------------------- /app/templates/_submit_comment.html: -------------------------------------------------------------------------------- 1 | {% import 'bootstrap/wtf.html' as wtf %} 2 | 3 |
4 |
5 | {#
#} 6 | {# #} 7 | {# 回复香飘叶子
#} 8 |
9 | {{ form.csrf_token }} 10 | {{ form.follow(type='hidden') }} 11 | {{ form.name.label }}{{ form.name(class='form-control', required='', value=current_user.username) }} 12 | {{ form.email.label }}{{ form.email(class='form-control', required='', value=current_user.email) }} 13 | {{ form.content.label }}{{ form.content(class='form-control', required='') }} 14 | 17 |
18 |
19 |
20 | -------------------------------------------------------------------------------- /app/templates/admin/admin_account.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/admin_base.html' %} 2 | 3 | {% block title %} 4 | Blog_mini -欢迎来到Blog_mini管理平台! 5 | {% endblock %} 6 | 7 | {% block admin_content %} 8 | 27 | 28 | 29 | 58 | 59 | 60 | 89 | {% endblock %} -------------------------------------------------------------------------------- /app/templates/admin/admin_base.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | 4 | {% block Content %} 5 |
6 |
7 |
8 | 26 |
27 |
28 | {% for category, message in get_flashed_messages(with_categories=true) %} 29 |
30 | 31 | {{ message }} 32 |
33 | {% endfor %} 34 | 35 | {% block admin_content %} 36 | {% endblock %} 37 |
38 |
39 |
40 | {% endblock %} 41 | 42 | {% block script %} 43 | {{ super() }} 44 | 45 | {% endblock %} 46 | -------------------------------------------------------------------------------- /app/templates/admin/blog_plugin_add.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/admin_base.html' %} 2 | 3 | {% block title %} 4 | Blog_mini -添加插件 5 | {% endblock %} 6 | 7 | {% block admin_content %} 8 |
9 |

添加插件

10 |
11 |
12 |
13 | {{ form.csrf_token }} 14 |
15 | {{ form.title.label }} 16 | {{ form.title(class='form-control', required='') }} 17 | {{ form.note.label }}(可选) 18 | {{ form.note(class='form-control') }} 19 | {{ form.content.label }} 20 | {{ form.content(id='pluginContent') }} 21 |
22 |
23 | 24 |
25 |
26 |
27 |
28 | {% endblock %} 29 | 30 | {% block script %} 31 | {{ super() }} 32 | 33 | 34 | {% endblock %} -------------------------------------------------------------------------------- /app/templates/admin/custom_blog_info.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/admin_base.html' %} 2 | 3 | {% block title %} 4 | Blog_mini -基本信息 5 | {% endblock %} 6 | 7 | {% block admin_content %} 8 |
9 |

基本信息

10 |
11 |
12 |
博客标题:
13 | {{ BlogInfo.query.first().title }} 14 |
个性签名:
15 | {{ BlogInfo.query.first().signature }} 16 |
导航样式:
17 | 18 | {% if BlogInfo.query.first().navbar == 'inverse' %} 19 | 魅力黑 20 | {% else %} 21 | 优雅白 22 | {% endif %} 23 | 24 | 31 |
32 |
33 | 34 | 35 | 63 | {% endblock %} -------------------------------------------------------------------------------- /app/templates/admin/custom_blog_plugin.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/admin_base.html' %} 2 | {% import "_macros.html" as macros %} 3 | 4 | {% block title %} 5 | Blog_mini -插件管理 6 | {% endblock %} 7 | 8 | {% block admin_content %} 9 |
10 |

插件管理

11 |
12 |

插件总数:{{ Plugin.query.count() }}

13 |
14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | {% for plugin in plugins %} 29 | 30 | 31 | 32 | 33 | 43 | 58 | {% if plugin.content != 'system_plugin' %} 59 | 65 | 71 | {% else %} 72 | 73 | 74 | {% endif %} 75 | 76 | {% endfor %} 77 | 78 |
序号插件名称备注排序启用修改删除
{{ plugin.order }}{{ plugin.title }}{{ plugin.note }} 34 | 36 | 37 | 38 | 40 | 41 | 42 | 44 | {% if plugin.disabled == True %} 45 | 48 | 49 | 50 | {% else %} 51 | 54 | 55 | 56 | {% endif %} 57 | 60 | 62 | 63 | 64 | 66 | 68 | 69 | 70 |
79 |
80 |
81 | 84 |
85 | 86 | 87 | 110 | {% endblock %} 111 | -------------------------------------------------------------------------------- /app/templates/admin/help_page.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/admin_base.html' %} 2 | 3 | {% block title %} 4 | Blog_mini -帮助 5 | {% endblock %} 6 | 7 | {% block admin_content %} 8 |
9 |

Blog_mini帮助页面

10 |
11 |
1.Blog_mini是什么?
12 |

13 |    Blog_mini由Python爱好者香飘叶子开发完成,是一个开源的个人博客系统,其采用Web框架为Flask, 14 | 有如下主要特点: 15 |

16 |

17 | 1.简洁的用户界面,使用前端框架为Bootstrap,支持响应式 18 |

19 |

20 | 2.强大的后台管理功能,一旦部署完成,即可轻松管理你的博客 21 |

22 |

23 | 3.通俗易懂的源代码,代码不会很复杂,方便阅读和理解 24 |

25 |

26 | 4.详细的部署文档,涵盖在CentOS/Ubuntu/Heroku等平台的部署 27 |

28 |

29 | 5.技术支持,对于部署和使用出现的问题,作者将提供无偿的技术支持 30 |

31 |

32 |    由于其具有以上特点,因此使用Blog_mini来作为个人博客平台,是一个非常不错的选择! 33 |

34 |
2.Blog_mini免费吗?
35 |

36 |    Blog_mini是开源的,所以绝对是免费的,并且你不用担心任何版权问题,因此你可以在GitHub上获得它的全部源代码, 37 | 并进行修改和扩展开发。 38 |

39 |
3.如何获得Blog_mini的帮助与支持?
40 |

41 |    本着自由与分享的精神,作者不仅将Blog_mini分享给大家,同时撰写了较为详尽的完整部署文档, 42 | 并且无偿提供技术支持,你可以在后面给出的链接地址中得到相关信息。 43 |

44 |
4.相关链接
45 |

Blog_mini源码地址:https://github.com/xpleaf/Blog_mini

46 |

个人社交博客系统:https://flasky-mini.herokuapp.com

47 |

51cto博客:http://xpleaf.blog.51cto.com(开源项目一栏)

48 | 有问题请在51cto博客上给我留言,作者承诺将无限期提供技术支持。 49 |
50 | {% endblock %} -------------------------------------------------------------------------------- /app/templates/admin/manage_articleTypes_nav.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/admin_base.html' %} 2 | {% import "_macros.html" as macros %} 3 | 4 | {% block title %} 5 | Blog_mini -分类导航 6 | {% endblock %} 7 | 8 | {% block admin_content %} 9 |
10 |

分类导航

11 |
12 |

导航总数:{{ Menu.query.count() }}

13 |
14 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | {% for menu in menus %} 32 | 33 | 34 | 35 | 46 | 56 | 62 | 68 | 69 | {% endfor %} 70 | 71 |
序号导航名称所含分类排序修改删除
{{ menu.order }}{{ menu.name }} 36 | {% if menu.types.count() %} 37 | {% for aritcleType in menu.types.all() %} 38 | 39 | {{ aritcleType.name }} 40 | 41 | {% endfor %} 42 | {% else %} 43 | 没有分类,该导航将不显示。 44 | {% endif %} 45 | 47 | 49 | 50 | 51 | 53 | 54 | 55 | 57 | 59 | 60 | 61 | 63 | 65 | 66 | 67 |
72 |
73 | 79 |
80 | 83 |
84 | 85 | 86 | 111 | 112 | 113 | 139 | 140 | 141 | 161 | {% endblock %} -------------------------------------------------------------------------------- /app/templates/admin/submit_articles.html: -------------------------------------------------------------------------------- 1 | {% extends 'admin/admin_base.html' %} 2 | 3 | {% block title %} 4 | Blog_mini -提交博文 5 | {% endblock %} 6 | 7 | {% block stylesheet %} 8 | {{ super() }} 9 | 11 | {% endblock %} 12 | 13 | {% block script %} 14 | {{ super() }} 15 | 16 | 17 | 18 | {% endblock %} 19 | 20 | {% block admin_content %} 21 |
22 |

发表博文

23 |
24 |
25 | {{ form.csrf_token }} 26 |
27 | {{ form.title.label(class='control-label') }}: 28 | {{ form.source(class='', required='') }} 29 | {{ form.title(class='submit-article-title', required='') }}(1-50字) 30 |
31 |
32 | {{ form.content() }} 33 |
34 |
35 | {{ form.types.label(class='control-label') }}: 36 | {{ form.types() }} 37 |
38 |
39 | {{ form.summary.label(class='control-label') }}(显示在博客首页)
40 | {{ form.summary(class='submit-article-summary form-control', required='') }} 41 |
42 |
43 | 44 |
45 |
46 |
47 | {% endblock %} -------------------------------------------------------------------------------- /app/templates/article_detials.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% import '_macros.html' as macros %} 3 | 4 | {% block title %} 5 | Blog_mini -{{ article.title }} 6 | {% endblock %} 7 | 8 | {% block content %} 9 |
10 | {% include '_article_info.html' %} 11 |
12 |
13 |

14 | {{ article.content | safe }} 15 |

16 |
17 |
18 |

19 | 20 | 博文最后更新时间: 21 | 22 | {{ moment(article.update_time.replace(microsecond=0)).format('LLL') }} 23 |

24 |
25 | {% if current_user.is_authenticated %} 26 |
27 | 28 | 32 | 33 |
34 | {% endif %} 35 |
36 |

评论

37 | {% include "_article_comments.html" %} 38 | 41 |

发表评论

42 | {% include "_submit_comment.html" %} 43 |
44 | {% endblock %} 45 | 46 | {% block stylesheet %} 47 | {{ super() }} 48 | 49 | {% endblock %} 50 | 51 | {% block script %} 52 | {{ super() }} 53 | 55 | 56 | 57 | {% endblock %} 58 | -------------------------------------------------------------------------------- /app/templates/auth/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 登陆Blog_mini管理后台 7 | 8 | 9 | 10 | 11 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /app/templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% import "_macros.html" as macros %} 3 | 4 | {% block content %} 5 | {% include "_article_entry.html" %} 6 | 13 | {% endblock %} -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | import os 2 | basedir = os.path.abspath(os.path.dirname(__file__)) 3 | 4 | 5 | class Config(): 6 | # DEBUG = True 7 | SQLALCHEMY_TRACK_MODIFICATIONS = True 8 | # SQLALCHEMY_COMMIT_ON_TEARDOWN = True 9 | SQLALCHEMY_RECORD_QUERIES = True 10 | SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \ 11 | 'sqlite:///' + os.path.join(basedir, 'data.sqlite') 12 | ARTICLES_PER_PAGE = 10 13 | COMMENTS_PER_PAGE = 6 14 | SECRET_KEY = 'secret key to protect from csrf' 15 | WTF_CSRF_SECRET_KEY = 'random key for form' # for csrf protection 16 | # Take good care of 'SECRET_KEY' and 'WTF_CSRF_SECRET_KEY', if you use the 17 | # bootstrap extension to create a form, it is Ok to use 'SECRET_KEY', 18 | # but when you use tha style like '{{ form.name.labey }}:{{ form.name() }}', 19 | # you must do this for yourself to use the wtf, more about this, you can 20 | # take a reference to the book <>. 21 | # But the book only have the version of English. 22 | 23 | @staticmethod 24 | def init_app(app): 25 | pass 26 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from flask.ext.script import Manager, Shell 3 | from flask.ext.migrate import Migrate, MigrateCommand 4 | from app import create_app, db 5 | from app.models import ArticleType, article_types, Source, \ 6 | Comment, Article, User, Menu, ArticleTypeSetting, BlogInfo, \ 7 | Plugin, BlogView 8 | 9 | app = create_app() 10 | manager = Manager(app) 11 | migrate = Migrate(app, db) 12 | manager.add_command('db', MigrateCommand) 13 | 14 | 15 | # Global variables to jiajia2 environment: 16 | app.jinja_env.globals['ArticleType'] = ArticleType 17 | app.jinja_env.globals['article_types'] = article_types 18 | app.jinja_env.globals['Menu'] = Menu 19 | app.jinja_env.globals['BlogInfo'] = BlogInfo 20 | app.jinja_env.globals['Plugin'] = Plugin 21 | app.jinja_env.globals['Source'] = Source 22 | app.jinja_env.globals['Article'] = Article 23 | app.jinja_env.globals['Comment'] = Comment 24 | app.jinja_env.globals['BlogView'] = BlogView 25 | 26 | 27 | def make_shell_context(): 28 | return dict(db=db, ArticleType=ArticleType,Source=Source, 29 | Comment=Comment, Article=Article, User=User, Menu=Menu, 30 | ArticleTypeSetting=ArticleTypeSetting, BlogInfo=BlogInfo, 31 | Plugin=Plugin, BlogView=BlogView) 32 | 33 | manager.add_command("shell", Shell(make_context=make_shell_context)) 34 | 35 | 36 | @manager.command 37 | def deploy(deploy_type): 38 | from flask.ext.migrate import upgrade 39 | from app.models import BlogInfo, User, ArticleTypeSetting, Source, \ 40 | ArticleType, Plugin, BlogView, Comment 41 | 42 | # upgrade database to the latest version 43 | upgrade() 44 | 45 | if deploy_type == 'product': 46 | # step_1:insert basic blog info 47 | BlogInfo.insert_blog_info() 48 | # step_2:insert admin account 49 | User.insert_admin(email='blog_mini@163.com', username='blog_mini', password='blog_mini') 50 | # step_3:insert system default setting 51 | ArticleTypeSetting.insert_system_setting() 52 | # step_4:insert default article sources 53 | Source.insert_sources() 54 | # step_5:insert default articleType 55 | ArticleType.insert_system_articleType() 56 | # step_6:insert system plugin 57 | Plugin.insert_system_plugin() 58 | # step_7:insert blog view 59 | BlogView.insert_view() 60 | 61 | # You must run `python manage.py deploy(product)` before run `python manage.py deploy(test_data)` 62 | if deploy_type == 'test_data': 63 | # step_1:insert navs 64 | Menu.insert_menus() 65 | # step_2:insert articleTypes 66 | ArticleType.insert_articleTypes() 67 | # step_3:generate random articles 68 | Article.generate_fake(100) 69 | # step_4:generate random comments 70 | Comment.generate_fake(300) 71 | # step_5:generate random replies 72 | Comment.generate_fake_replies(100) 73 | # step_4:generate random comments 74 | Comment.generate_fake(300) 75 | 76 | 77 | if __name__ == '__main__': 78 | manager.run() 79 | -------------------------------------------------------------------------------- /migrations/README: -------------------------------------------------------------------------------- 1 | Generic single-database configuration. -------------------------------------------------------------------------------- /migrations/alembic.ini: -------------------------------------------------------------------------------- 1 | # A generic, single database configuration. 2 | 3 | [alembic] 4 | # template used to generate migration files 5 | # file_template = %%(rev)s_%%(slug)s 6 | 7 | # set to 'true' to run the environment during 8 | # the 'revision' command, regardless of autogenerate 9 | # revision_environment = false 10 | 11 | 12 | # Logging configuration 13 | [loggers] 14 | keys = root,sqlalchemy,alembic 15 | 16 | [handlers] 17 | keys = console 18 | 19 | [formatters] 20 | keys = generic 21 | 22 | [logger_root] 23 | level = WARN 24 | handlers = console 25 | qualname = 26 | 27 | [logger_sqlalchemy] 28 | level = WARN 29 | handlers = 30 | qualname = sqlalchemy.engine 31 | 32 | [logger_alembic] 33 | level = INFO 34 | handlers = 35 | qualname = alembic 36 | 37 | [handler_console] 38 | class = StreamHandler 39 | args = (sys.stderr,) 40 | level = NOTSET 41 | formatter = generic 42 | 43 | [formatter_generic] 44 | format = %(levelname)-5.5s [%(name)s] %(message)s 45 | datefmt = %H:%M:%S 46 | -------------------------------------------------------------------------------- /migrations/env.py: -------------------------------------------------------------------------------- 1 | from __future__ import with_statement 2 | from alembic import context 3 | from sqlalchemy import engine_from_config, pool 4 | from logging.config import fileConfig 5 | import logging 6 | 7 | # this is the Alembic Config object, which provides 8 | # access to the values within the .ini file in use. 9 | config = context.config 10 | 11 | # Interpret the config file for Python logging. 12 | # This line sets up loggers basically. 13 | fileConfig(config.config_file_name) 14 | logger = logging.getLogger('alembic.env') 15 | 16 | # add your model's MetaData object here 17 | # for 'autogenerate' support 18 | # from myapp import mymodel 19 | # target_metadata = mymodel.Base.metadata 20 | from flask import current_app 21 | config.set_main_option('sqlalchemy.url', 22 | current_app.config.get('SQLALCHEMY_DATABASE_URI')) 23 | target_metadata = current_app.extensions['migrate'].db.metadata 24 | 25 | # other values from the config, defined by the needs of env.py, 26 | # can be acquired: 27 | # my_important_option = config.get_main_option("my_important_option") 28 | # ... etc. 29 | 30 | 31 | def run_migrations_offline(): 32 | """Run migrations in 'offline' mode. 33 | 34 | This configures the context with just a URL 35 | and not an Engine, though an Engine is acceptable 36 | here as well. By skipping the Engine creation 37 | we don't even need a DBAPI to be available. 38 | 39 | Calls to context.execute() here emit the given string to the 40 | script output. 41 | 42 | """ 43 | url = config.get_main_option("sqlalchemy.url") 44 | context.configure(url=url) 45 | 46 | with context.begin_transaction(): 47 | context.run_migrations() 48 | 49 | 50 | def run_migrations_online(): 51 | """Run migrations in 'online' mode. 52 | 53 | In this scenario we need to create an Engine 54 | and associate a connection with the context. 55 | 56 | """ 57 | 58 | # this callback is used to prevent an auto-migration from being generated 59 | # when there are no changes to the schema 60 | # reference: http://alembic.readthedocs.org/en/latest/cookbook.html 61 | def process_revision_directives(context, revision, directives): 62 | if getattr(config.cmd_opts, 'autogenerate', False): 63 | script = directives[0] 64 | if script.upgrade_ops.is_empty(): 65 | directives[:] = [] 66 | logger.info('No changes in schema detected.') 67 | 68 | engine = engine_from_config(config.get_section(config.config_ini_section), 69 | prefix='sqlalchemy.', 70 | poolclass=pool.NullPool) 71 | 72 | connection = engine.connect() 73 | context.configure(connection=connection, 74 | target_metadata=target_metadata, 75 | process_revision_directives=process_revision_directives, 76 | **current_app.extensions['migrate'].configure_args) 77 | 78 | try: 79 | with context.begin_transaction(): 80 | context.run_migrations() 81 | finally: 82 | connection.close() 83 | 84 | if context.is_offline_mode(): 85 | run_migrations_offline() 86 | else: 87 | run_migrations_online() 88 | -------------------------------------------------------------------------------- /migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = ${repr(up_revision)} 11 | down_revision = ${repr(down_revision)} 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | ${imports if imports else ""} 16 | 17 | def upgrade(): 18 | ${upgrades if upgrades else "pass"} 19 | 20 | 21 | def downgrade(): 22 | ${downgrades if downgrades else "pass"} 23 | -------------------------------------------------------------------------------- /migrations/versions/051691f120e6_fit_to_mysql.py: -------------------------------------------------------------------------------- 1 | """fit to MySQL 2 | 3 | Revision ID: 051691f120e6 4 | Revises: None 5 | Create Date: 2016-03-06 19:11:38.238238 6 | 7 | """ 8 | 9 | # revision identifiers, used by Alembic. 10 | revision = '051691f120e6' 11 | down_revision = None 12 | 13 | from alembic import op 14 | import sqlalchemy as sa 15 | 16 | 17 | def upgrade(): 18 | ### commands auto generated by Alembic - please adjust! ### 19 | op.create_table('articleTypeSettings', 20 | sa.Column('id', sa.Integer(), nullable=False), 21 | sa.Column('name', sa.String(length=64), nullable=True), 22 | sa.Column('protected', sa.Boolean(), nullable=True), 23 | sa.Column('hide', sa.Boolean(), nullable=True), 24 | sa.PrimaryKeyConstraint('id'), 25 | sa.UniqueConstraint('name') 26 | ) 27 | op.create_table('blog_info', 28 | sa.Column('id', sa.Integer(), nullable=False), 29 | sa.Column('title', sa.String(length=64), nullable=True), 30 | sa.Column('signature', sa.Text(), nullable=True), 31 | sa.Column('navbar', sa.String(length=64), nullable=True), 32 | sa.PrimaryKeyConstraint('id') 33 | ) 34 | op.create_table('blog_view', 35 | sa.Column('id', sa.Integer(), nullable=False), 36 | sa.Column('num_of_view', sa.BigInteger(), nullable=True), 37 | sa.PrimaryKeyConstraint('id') 38 | ) 39 | op.create_table('menus', 40 | sa.Column('id', sa.Integer(), nullable=False), 41 | sa.Column('name', sa.String(length=64), nullable=True), 42 | sa.Column('order', sa.Integer(), nullable=False), 43 | sa.PrimaryKeyConstraint('id'), 44 | sa.UniqueConstraint('name') 45 | ) 46 | op.create_table('plugins', 47 | sa.Column('id', sa.Integer(), nullable=False), 48 | sa.Column('title', sa.String(length=64), nullable=True), 49 | sa.Column('note', sa.Text(), nullable=True), 50 | sa.Column('content', sa.Text(), nullable=True), 51 | sa.Column('order', sa.Integer(), nullable=True), 52 | sa.Column('disabled', sa.Boolean(), nullable=True), 53 | sa.PrimaryKeyConstraint('id'), 54 | sa.UniqueConstraint('title') 55 | ) 56 | op.create_table('sources', 57 | sa.Column('id', sa.Integer(), nullable=False), 58 | sa.Column('name', sa.String(length=64), nullable=True), 59 | sa.PrimaryKeyConstraint('id'), 60 | sa.UniqueConstraint('name') 61 | ) 62 | op.create_table('user', 63 | sa.Column('id', sa.Integer(), nullable=False), 64 | sa.Column('email', sa.String(length=64), nullable=True), 65 | sa.Column('username', sa.String(length=64), nullable=True), 66 | sa.Column('password_hash', sa.String(length=128), nullable=True), 67 | sa.Column('avatar_hash', sa.String(length=32), nullable=True), 68 | sa.PrimaryKeyConstraint('id') 69 | ) 70 | op.create_index(op.f('ix_user_email'), 'user', ['email'], unique=True) 71 | op.create_index(op.f('ix_user_username'), 'user', ['username'], unique=True) 72 | op.create_table('articleTypes', 73 | sa.Column('id', sa.Integer(), nullable=False), 74 | sa.Column('name', sa.String(length=64), nullable=True), 75 | sa.Column('introduction', sa.Text(), nullable=True), 76 | sa.Column('menu_id', sa.Integer(), nullable=True), 77 | sa.Column('setting_id', sa.Integer(), nullable=True), 78 | sa.ForeignKeyConstraint(['menu_id'], ['menus.id'], ), 79 | sa.ForeignKeyConstraint(['setting_id'], ['articleTypeSettings.id'], ), 80 | sa.PrimaryKeyConstraint('id'), 81 | sa.UniqueConstraint('name') 82 | ) 83 | op.create_table('articles', 84 | sa.Column('id', sa.Integer(), nullable=False), 85 | sa.Column('title', sa.String(length=64), nullable=True), 86 | sa.Column('content', sa.Text(), nullable=True), 87 | sa.Column('summary', sa.Text(), nullable=True), 88 | sa.Column('create_time', sa.DateTime(), nullable=True), 89 | sa.Column('update_time', sa.DateTime(), nullable=True), 90 | sa.Column('num_of_view', sa.Integer(), nullable=True), 91 | sa.Column('articleType_id', sa.Integer(), nullable=True), 92 | sa.Column('source_id', sa.Integer(), nullable=True), 93 | sa.ForeignKeyConstraint(['articleType_id'], ['articleTypes.id'], ), 94 | sa.ForeignKeyConstraint(['source_id'], ['sources.id'], ), 95 | sa.PrimaryKeyConstraint('id'), 96 | sa.UniqueConstraint('title') 97 | ) 98 | op.create_index(op.f('ix_articles_create_time'), 'articles', ['create_time'], unique=False) 99 | op.create_index(op.f('ix_articles_update_time'), 'articles', ['update_time'], unique=False) 100 | op.create_table('comments', 101 | sa.Column('id', sa.Integer(), nullable=False), 102 | sa.Column('content', sa.Text(), nullable=True), 103 | sa.Column('timestamp', sa.DateTime(), nullable=True), 104 | sa.Column('author_name', sa.String(length=64), nullable=True), 105 | sa.Column('author_email', sa.String(length=64), nullable=True), 106 | sa.Column('avatar_hash', sa.String(length=32), nullable=True), 107 | sa.Column('article_id', sa.Integer(), nullable=True), 108 | sa.Column('disabled', sa.Boolean(), nullable=True), 109 | sa.Column('comment_type', sa.String(length=64), nullable=True), 110 | sa.Column('reply_to', sa.String(length=128), nullable=True), 111 | sa.ForeignKeyConstraint(['article_id'], ['articles.id'], ), 112 | sa.PrimaryKeyConstraint('id') 113 | ) 114 | op.create_table('follows', 115 | sa.Column('follower_id', sa.Integer(), nullable=False), 116 | sa.Column('followed_id', sa.Integer(), nullable=False), 117 | sa.ForeignKeyConstraint(['followed_id'], ['comments.id'], ), 118 | sa.ForeignKeyConstraint(['follower_id'], ['comments.id'], ), 119 | sa.PrimaryKeyConstraint('follower_id', 'followed_id') 120 | ) 121 | ### end Alembic commands ### 122 | 123 | 124 | def downgrade(): 125 | ### commands auto generated by Alembic - please adjust! ### 126 | op.drop_table('follows') 127 | op.drop_table('comments') 128 | op.drop_index(op.f('ix_articles_update_time'), table_name='articles') 129 | op.drop_index(op.f('ix_articles_create_time'), table_name='articles') 130 | op.drop_table('articles') 131 | op.drop_table('articleTypes') 132 | op.drop_index(op.f('ix_user_username'), table_name='user') 133 | op.drop_index(op.f('ix_user_email'), table_name='user') 134 | op.drop_table('user') 135 | op.drop_table('sources') 136 | op.drop_table('plugins') 137 | op.drop_table('menus') 138 | op.drop_table('blog_view') 139 | op.drop_table('blog_info') 140 | op.drop_table('articleTypeSettings') 141 | ### end Alembic commands ### 142 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | -r requirements/common.txt 2 | gunicorn==19.4.5 3 | psycopg2==2.6.1 4 | -------------------------------------------------------------------------------- /requirements/common.txt: -------------------------------------------------------------------------------- 1 | Flask==0.10.1 2 | Flask-Script==2.0.5 3 | Flask-SQLAlchemy==2.1 4 | Flask-Migrate==1.7.0 5 | Flask-WTF==0.12 6 | Flask-Bootstrap==3.3.5.7 7 | WTForms==2.1 8 | itsdangerous==0.24 9 | Jinja2==2.8 10 | MarkupSafe==0.23 11 | SQLAlchemy==1.0.11 12 | Werkzeug==0.11.3 13 | wheel==0.24.0 14 | flask-login==0.3.2 15 | flask-moment==0.5.1 16 | ForgeryPy==0.1 17 | gunicorn==19.4.5 18 | -------------------------------------------------------------------------------- /requirements/dev.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpleaf/Blog_mini/2dc23b8b0f77e89d0caef33bf71189e94465abd8/requirements/dev.txt --------------------------------------------------------------------------------