├── .gitignore
├── LICENSE
├── README.md
├── composer.json
└── src
├── EndaEditor.php
├── EndaEditorServiceProvider.php
├── Facade
└── EndaEditorFacade.php
├── Parsedown.php
└── config
├── editor.php
├── editor
├── css
│ ├── editor.css
│ ├── editor.css.map
│ ├── pygment_trac.css
│ ├── stylesheet.css
│ └── zoom.css
├── images
│ ├── code.png
│ ├── editor@2x.png
│ ├── loader.gif
│ ├── pattern.png
│ ├── tar.png
│ ├── top.png
│ └── zip.png
└── js
│ ├── MIDI.js
│ ├── bacheditor.js
│ ├── bootstrap3-typeahead.js
│ ├── fileupload.js
│ ├── highlight.js
│ ├── marimba-mp3.js
│ ├── modal.js
│ ├── piano.js
│ ├── template.js
│ └── zoom.js
└── views
├── decode.blade.php
└── head.blade.php
/.gitignore:
--------------------------------------------------------------------------------
1 | /bootstrap/compiled.php
2 | .env.*.php
3 | .env.php
4 | .env
5 | .idea
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
203 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # laravel-5-markdown-editor
2 | Based on the markdown editor laravel 5
3 |
4 | 一个基于 laravel 5 的markdown 编辑器
5 |
6 | 本项目基于 html&js 一个有情怀的编辑器二次开发完成 [传送门](https://github.com/Integ/BachEditor)
7 |
8 |
9 | # 安装使用详细教程
10 |
11 | phphub: [https://phphub.org/topics/853](https://phphub.org/topics/853)
12 |
13 | 如果访问 phphub 比较慢的同学,可以访问这个
14 |
15 | SegmentFault:[http://segmentfault.com/a/1190000002780158](http://segmentfault.com/a/1190000002780158)
16 |
17 | # 不需要敲语法可界面操作的功能
18 | 1. 加粗字体
19 | 2. 加斜字体
20 | 3. `无需手写 md插入链接`
21 | 4. 引用
22 | 5. `无需手写 md 语法插入图片`
23 | 6. 数字列表
24 | 7. 普通列表
25 | 8. 标题
26 | 9. 分割
27 | 10. 撤销
28 | 11. 重做
29 | 12. 全屏
30 |
31 | # Bug 反馈&交流
32 |
33 | 欢迎加入我们的 laravel 学习小组:`365969825`
34 |
35 | # 预览
36 |
37 |
38 |
39 |
40 | # Update Log
41 |
42 | `2015-05-18` 初版提交
43 |
44 | `2015-05-19` 图片上传移植到扩展内部处理
45 |
46 | `2015-05-19` 新增解析 markdown 为 html 功能
47 |
48 | # Installation
49 |
50 | 1.在 `composer.json` 的 require里 加入
51 |
52 | ```
53 | "yuanchao/laravel-5-markdown-editor": "dev-master"
54 | ```
55 | 2.执行 `composer update`
56 |
57 | 3.在config/app.php 的 `providers` 数组加入一条
58 |
59 | ```
60 | 'YuanChao\Editor\EndaEditorServiceProvider'
61 | ```
62 |
63 | 4.在config/app.php 的 `aliases` 数组加入一条
64 |
65 | ```
66 | 'EndaEditor' => 'YuanChao\Editor\Facade\EndaEditorFacade'
67 |
68 | ```
69 |
70 | 5.执行 `php artisan vendor:publish --tag=EndaEditor`
71 |
72 | 执行完上面的命令后,会生成配置文件和视图文件到你的 config/ 和 views/vendor 目录
73 |
74 | # Usage
75 |
76 | 1.在需要编辑器的地方插入以下代码
77 |
78 | ```
79 | // 引入编辑器代码
80 | @include('editor::head')
81 |
82 | // 编辑器一定要被一个 class 为 editor 的容器包住
83 |
84 | // 创建一个 textarea 而已,具体的看手册,主要在于它的 id 为 myEditor
85 | {!! Form::textarea('content', '', ['class' => 'form-control','id'=>'myEditor']) !!}
86 |
87 | // 上面的 Form::textarea ,在laravel 5 中被提了出去,如果你没安装的话,直接这样用
88 |
89 |
90 | // 主要还是在容器的 ID 为 myEditor 就行
91 |
92 |
93 |
94 | ```
95 |
96 | 这个时候,编辑器就出来啦~
97 |
98 | #### 图片上传移植到扩展内部处理
99 |
100 | `图片上传移植到扩展的功能上传时间为 2015-05-19 10:40 如果在这个时间前安装的朋友,请先更新`
101 |
102 | 2.图片上传配置,打开config/editor.php 配置文件,修改里面的 `uploadUrl` 配置项,为你的处理上传的 action
103 |
104 | 我的上传 action 代码为
105 |
106 | ```
107 | use EndaEditor;
108 |
109 | public function postUpload(){
110 |
111 |
112 | // endaEdit 为你 public 下的目录 update 2015-05-19
113 | $data = EndaEditor::uploadImgFile('endaEdit');
114 |
115 | return json_encode($data);
116 | }
117 |
118 |
119 | ```
120 |
121 | 3.链接添加功能添加了方便的添加系统内部文章的特性,首先在config/editor.php配置文件添加 `ajaxTopicSearchUrl` 配置项,关于返回的数据格式,请在配置文件中查看注释。
122 |
123 | 之后在您没有选中任何字符的情况下点击添加链接,将会看到多了一个标题输入框,您输入一些字符,它会根据 `ajaxTopicSearchUrl` 获得的文章标题列表来生成自动补全的下拉列表。
124 |
125 | 当您选中某个文章之后,下面的链接也会自动被填上。
126 | ###完成以上这些配置,你就可以在线插入图片啦
127 |
128 |
129 | ### 新增解析 markdown 为 html 功能
130 |
131 | 头部引用文件
132 | ```
133 | use EndaEditor;
134 |
135 | ```
136 |
137 | 列子如下:
138 | ```
139 |
140 | $art = Article::find(16);
141 |
142 |
143 | return view('test',[
144 | 'content'=>EndaEditor::MarkDecode($art->content)
145 | ]);
146 |
147 |
148 | ```
149 |
150 | 直接把需要解析的 markdown 扔进这个方法就行
151 |
152 | ```
153 | EndaEditor::MarkDecode("#我是参数")
154 |
155 | ```
156 |
157 | 为了保证图片的显示正常,加入[zoom插件](https://github.com/fat/zoom.js)
158 |
159 | 在需要解码的页面确保引入了bootstrap,并加入如下代码
160 | ```
161 | @include('editor::decode')
162 |
163 | ```
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "yuanchao/laravel-5-markdown-editor",
3 | "description": "Based on the markdown editor laravel 5",
4 | "authors": [
5 | {
6 | "name": "yuanchao",
7 | "email": "653069653@qq.com"
8 | }
9 | ],
10 | "license": "MIT",
11 | "minimum-stability": "dev",
12 | "require": {},
13 | "autoload": {
14 | "psr-4": {
15 | "YuanChao\\Editor\\":"src/"
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/EndaEditor.php:
--------------------------------------------------------------------------------
1 |
5 | * Time: 2015.05.18 下午2:11
6 | */
7 | namespace YuanChao\Editor;
8 |
9 | use Illuminate\Support\Facades\Request;
10 |
11 | class EndaEditor{
12 |
13 | static $_errors=array();
14 |
15 | protected static function addError($message){
16 | if(!empty($message)){
17 | self::$_errors[] = $message;
18 | }
19 | }
20 |
21 | protected static function getLastError(){
22 | return empty(self::$_errors) ? '' : array_pop(self::$_errors);
23 | }
24 |
25 | /**
26 | * EndaEditor Upload ImgFile
27 | * @param string $path
28 | * @return array
29 | */
30 | public static function uploadImgFile($path){
31 | try{
32 | // File Upload
33 | if (Request::hasFile('image')){
34 | $pic = Request::file('image');
35 | if($pic->isValid()){
36 | $newName = md5(rand(1,1000).$pic->getClientOriginalName()).".".$pic->getClientOriginalExtension();
37 | $pic->move($path,$newName);
38 | $url = asset($path.'/'.$newName);
39 | }else{
40 | self::addError('The file is invalid');
41 | }
42 | }else{
43 | self::addError('Not File');
44 | }
45 | }catch (\Exception $e){
46 | self::addError($e->getMessage());
47 | }
48 |
49 | $data = array(
50 | 'status'=>empty($message)?0:1,
51 | 'message'=>self::getLastError(),
52 | 'url'=>!empty($url)?$url:''
53 | );
54 |
55 | return $data;
56 | }
57 |
58 |
59 | /**
60 | * 转换 mark 文本
61 | * @param $markdownText
62 | * @return string
63 | */
64 | public static function MarkDecode($markdownText){
65 | $parsedown = new \YuanChao\Editor\Parsedown();
66 | return $parsedown->text($markdownText);
67 | }
68 |
69 | }
--------------------------------------------------------------------------------
/src/EndaEditorServiceProvider.php:
--------------------------------------------------------------------------------
1 | loadViewsFrom(__DIR__.'/config/views', 'editor');
17 |
18 | $this->publishes([
19 | __DIR__.'/config/views' => base_path('resources/views/vendor/editor'),
20 | ],'EndaEditor');
21 | $this->publishes([
22 | __DIR__.'/config/editor' => base_path('public/plugin/editor'),
23 | ],'EndaEditor');
24 | $this->publishes([
25 | __DIR__.'/config/editor.php' => config_path('editor.php'),
26 | ],'EndaEditor');
27 | }
28 |
29 | /**
30 | * Register the application services.
31 | *
32 | * @return void
33 | */
34 | public function register()
35 | {
36 | //
37 | $this->app->singleton('EndaEditor', function ($app) {
38 | return new \YuanChao\Editor\EndaEditor;
39 | });
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/Facade/EndaEditorFacade.php:
--------------------------------------------------------------------------------
1 |
4 | * Time: 2015.05.18 上午10:33
5 | */
6 | namespace YuanChao\Editor\Facade;
7 | use Illuminate\Support\Facades\Facade;
8 |
9 | class EndaEditorFacade extends Facade{
10 | protected static function getFacadeAccessor(){
11 | return 'EndaEditor';
12 | }
13 | }
--------------------------------------------------------------------------------
/src/Parsedown.php:
--------------------------------------------------------------------------------
1 |
4 | * Time: 2015.05.19 下午5:34
5 | */
6 | namespace YuanChao\Editor;
7 | class Parsedown
8 | {
9 | # ~
10 |
11 | const version = '1.5.3';
12 |
13 | # ~
14 |
15 | function text($text)
16 | {
17 | # make sure no definitions are set
18 | $this->DefinitionData = array();
19 |
20 | # standardize line breaks
21 | $text = str_replace(array("\r\n", "\r"), "\n", $text);
22 |
23 | # remove surrounding line breaks
24 | $text = trim($text, "\n");
25 |
26 | # split text into lines
27 | $lines = explode("\n", $text);
28 |
29 | # iterate through lines to identify blocks
30 | $markup = $this->lines($lines);
31 |
32 | # trim line breaks
33 | $markup = trim($markup, "\n");
34 |
35 | return $markup;
36 | }
37 |
38 | #
39 | # Setters
40 | #
41 |
42 | function setBreaksEnabled($breaksEnabled)
43 | {
44 | $this->breaksEnabled = $breaksEnabled;
45 |
46 | return $this;
47 | }
48 |
49 | protected $breaksEnabled;
50 |
51 | function setMarkupEscaped($markupEscaped)
52 | {
53 | $this->markupEscaped = $markupEscaped;
54 |
55 | return $this;
56 | }
57 |
58 | protected $markupEscaped;
59 |
60 | function setUrlsLinked($urlsLinked)
61 | {
62 | $this->urlsLinked = $urlsLinked;
63 |
64 | return $this;
65 | }
66 |
67 | protected $urlsLinked = true;
68 |
69 | #
70 | # Lines
71 | #
72 |
73 | protected $BlockTypes = array(
74 | '#' => array('Header'),
75 | '*' => array('Rule', 'List'),
76 | '+' => array('List'),
77 | '-' => array('SetextHeader', 'Table', 'Rule', 'List'),
78 | '0' => array('List'),
79 | '1' => array('List'),
80 | '2' => array('List'),
81 | '3' => array('List'),
82 | '4' => array('List'),
83 | '5' => array('List'),
84 | '6' => array('List'),
85 | '7' => array('List'),
86 | '8' => array('List'),
87 | '9' => array('List'),
88 | ':' => array('Table'),
89 | '<' => array('Comment', 'Markup'),
90 | '=' => array('SetextHeader'),
91 | '>' => array('Quote'),
92 | '[' => array('Reference'),
93 | '_' => array('Rule'),
94 | '`' => array('FencedCode'),
95 | '|' => array('Table'),
96 | '~' => array('FencedCode'),
97 | );
98 |
99 | # ~
100 |
101 | protected $DefinitionTypes = array(
102 | '[' => array('Reference'),
103 | );
104 |
105 | # ~
106 |
107 | protected $unmarkedBlockTypes = array(
108 | 'Code',
109 | );
110 |
111 | #
112 | # Blocks
113 | #
114 |
115 | private function lines(array $lines)
116 | {
117 | $CurrentBlock = null;
118 |
119 | foreach ($lines as $line)
120 | {
121 | if (chop($line) === '')
122 | {
123 | if (isset($CurrentBlock))
124 | {
125 | $CurrentBlock['interrupted'] = true;
126 | }
127 |
128 | continue;
129 | }
130 |
131 | if (strpos($line, "\t") !== false)
132 | {
133 | $parts = explode("\t", $line);
134 |
135 | $line = $parts[0];
136 |
137 | unset($parts[0]);
138 |
139 | foreach ($parts as $part)
140 | {
141 | $shortage = 4 - mb_strlen($line, 'utf-8') % 4;
142 |
143 | $line .= str_repeat(' ', $shortage);
144 | $line .= $part;
145 | }
146 | }
147 |
148 | $indent = 0;
149 |
150 | while (isset($line[$indent]) and $line[$indent] === ' ')
151 | {
152 | $indent ++;
153 | }
154 |
155 | $text = $indent > 0 ? substr($line, $indent) : $line;
156 |
157 | # ~
158 |
159 | $Line = array('body' => $line, 'indent' => $indent, 'text' => $text);
160 |
161 | # ~
162 |
163 | if (isset($CurrentBlock['incomplete']))
164 | {
165 | $Block = $this->{'block'.$CurrentBlock['type'].'Continue'}($Line, $CurrentBlock);
166 |
167 | if (isset($Block))
168 | {
169 | $CurrentBlock = $Block;
170 |
171 | continue;
172 | }
173 | else
174 | {
175 | if (method_exists($this, 'block'.$CurrentBlock['type'].'Complete'))
176 | {
177 | $CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock);
178 | }
179 |
180 | unset($CurrentBlock['incomplete']);
181 | }
182 | }
183 |
184 | # ~
185 |
186 | $marker = $text[0];
187 |
188 | # ~
189 |
190 | $blockTypes = $this->unmarkedBlockTypes;
191 |
192 | if (isset($this->BlockTypes[$marker]))
193 | {
194 | foreach ($this->BlockTypes[$marker] as $blockType)
195 | {
196 | $blockTypes []= $blockType;
197 | }
198 | }
199 |
200 | #
201 | # ~
202 |
203 | foreach ($blockTypes as $blockType)
204 | {
205 | $Block = $this->{'block'.$blockType}($Line, $CurrentBlock);
206 |
207 | if (isset($Block))
208 | {
209 | $Block['type'] = $blockType;
210 |
211 | if ( ! isset($Block['identified']))
212 | {
213 | $Blocks []= $CurrentBlock;
214 |
215 | $Block['identified'] = true;
216 | }
217 |
218 | if (method_exists($this, 'block'.$blockType.'Continue'))
219 | {
220 | $Block['incomplete'] = true;
221 | }
222 |
223 | $CurrentBlock = $Block;
224 |
225 | continue 2;
226 | }
227 | }
228 |
229 | # ~
230 |
231 | if (isset($CurrentBlock) and ! isset($CurrentBlock['type']) and ! isset($CurrentBlock['interrupted']))
232 | {
233 | $CurrentBlock['element']['text'] .= "\n".$text;
234 | }
235 | else
236 | {
237 | $Blocks []= $CurrentBlock;
238 |
239 | $CurrentBlock = $this->paragraph($Line);
240 |
241 | $CurrentBlock['identified'] = true;
242 | }
243 | }
244 |
245 | # ~
246 |
247 | if (isset($CurrentBlock['incomplete']) and method_exists($this, 'block'.$CurrentBlock['type'].'Complete'))
248 | {
249 | $CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock);
250 | }
251 |
252 | # ~
253 |
254 | $Blocks []= $CurrentBlock;
255 |
256 | unset($Blocks[0]);
257 |
258 | # ~
259 |
260 | $markup = '';
261 |
262 | foreach ($Blocks as $Block)
263 | {
264 | if (isset($Block['hidden']))
265 | {
266 | continue;
267 | }
268 |
269 | $markup .= "\n";
270 | $markup .= isset($Block['markup']) ? $Block['markup'] : $this->element($Block['element']);
271 | }
272 |
273 | $markup .= "\n";
274 |
275 | # ~
276 |
277 | return $markup;
278 | }
279 |
280 | #
281 | # Code
282 |
283 | protected function blockCode($Line, $Block = null)
284 | {
285 | if (isset($Block) and ! isset($Block['type']) and ! isset($Block['interrupted']))
286 | {
287 | return;
288 | }
289 |
290 | if ($Line['indent'] >= 4)
291 | {
292 | $text = substr($Line['body'], 4);
293 |
294 | $Block = array(
295 | 'element' => array(
296 | 'name' => 'pre',
297 | 'handler' => 'element',
298 | 'text' => array(
299 | 'name' => 'code',
300 | 'text' => $text,
301 | ),
302 | ),
303 | );
304 |
305 | return $Block;
306 | }
307 | }
308 |
309 | protected function blockCodeContinue($Line, $Block)
310 | {
311 | if ($Line['indent'] >= 4)
312 | {
313 | if (isset($Block['interrupted']))
314 | {
315 | $Block['element']['text']['text'] .= "\n";
316 |
317 | unset($Block['interrupted']);
318 | }
319 |
320 | $Block['element']['text']['text'] .= "\n";
321 |
322 | $text = substr($Line['body'], 4);
323 |
324 | $Block['element']['text']['text'] .= $text;
325 |
326 | return $Block;
327 | }
328 | }
329 |
330 | protected function blockCodeComplete($Block)
331 | {
332 | $text = $Block['element']['text']['text'];
333 |
334 | $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
335 |
336 | $Block['element']['text']['text'] = $text;
337 |
338 | return $Block;
339 | }
340 |
341 | #
342 | # Comment
343 |
344 | protected function blockComment($Line)
345 | {
346 | if ($this->markupEscaped)
347 | {
348 | return;
349 | }
350 |
351 | if (isset($Line['text'][3]) and $Line['text'][3] === '-' and $Line['text'][2] === '-' and $Line['text'][1] === '!')
352 | {
353 | $Block = array(
354 | 'markup' => $Line['body'],
355 | );
356 |
357 | if (preg_match('/-->$/', $Line['text']))
358 | {
359 | $Block['closed'] = true;
360 | }
361 |
362 | return $Block;
363 | }
364 | }
365 |
366 | protected function blockCommentContinue($Line, array $Block)
367 | {
368 | if (isset($Block['closed']))
369 | {
370 | return;
371 | }
372 |
373 | $Block['markup'] .= "\n" . $Line['body'];
374 |
375 | if (preg_match('/-->$/', $Line['text']))
376 | {
377 | $Block['closed'] = true;
378 | }
379 |
380 | return $Block;
381 | }
382 |
383 | #
384 | # Fenced Code
385 |
386 | protected function blockFencedCode($Line)
387 | {
388 | if (preg_match('/^(['.$Line['text'][0].']{3,})[ ]*([\w-]+)?[ ]*$/', $Line['text'], $matches))
389 | {
390 | $Element = array(
391 | 'name' => 'code',
392 | 'text' => '',
393 | );
394 |
395 | if (isset($matches[2]))
396 | {
397 | $class = 'language-'.$matches[2];
398 |
399 | $Element['attributes'] = array(
400 | 'class' => $class,
401 | );
402 | }
403 |
404 | $Block = array(
405 | 'char' => $Line['text'][0],
406 | 'element' => array(
407 | 'name' => 'pre',
408 | 'handler' => 'element',
409 | 'text' => $Element,
410 | ),
411 | );
412 |
413 | return $Block;
414 | }
415 | }
416 |
417 | protected function blockFencedCodeContinue($Line, $Block)
418 | {
419 | if (isset($Block['complete']))
420 | {
421 | return;
422 | }
423 |
424 | if (isset($Block['interrupted']))
425 | {
426 | $Block['element']['text']['text'] .= "\n";
427 |
428 | unset($Block['interrupted']);
429 | }
430 |
431 | if (preg_match('/^'.$Block['char'].'{3,}[ ]*$/', $Line['text']))
432 | {
433 | $Block['element']['text']['text'] = substr($Block['element']['text']['text'], 1);
434 |
435 | $Block['complete'] = true;
436 |
437 | return $Block;
438 | }
439 |
440 | $Block['element']['text']['text'] .= "\n".$Line['body'];;
441 |
442 | return $Block;
443 | }
444 |
445 | protected function blockFencedCodeComplete($Block)
446 | {
447 | $text = $Block['element']['text']['text'];
448 |
449 | $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
450 |
451 | $Block['element']['text']['text'] = $text;
452 |
453 | return $Block;
454 | }
455 |
456 | #
457 | # Header
458 |
459 | protected function blockHeader($Line)
460 | {
461 | if (isset($Line['text'][1]))
462 | {
463 | $level = 1;
464 |
465 | while (isset($Line['text'][$level]) and $Line['text'][$level] === '#')
466 | {
467 | $level ++;
468 | }
469 |
470 | if ($level > 6)
471 | {
472 | return;
473 | }
474 |
475 | $text = trim($Line['text'], '# ');
476 |
477 | $Block = array(
478 | 'element' => array(
479 | 'name' => 'h' . min(6, $level),
480 | 'text' => $text,
481 | 'handler' => 'line',
482 | ),
483 | );
484 |
485 | return $Block;
486 | }
487 | }
488 |
489 | #
490 | # List
491 |
492 | protected function blockList($Line)
493 | {
494 | list($name, $pattern) = $Line['text'][0] <= '-' ? array('ul', '[*+-]') : array('ol', '[0-9]+[.]');
495 |
496 | if (preg_match('/^('.$pattern.'[ ]+)(.*)/', $Line['text'], $matches))
497 | {
498 | $Block = array(
499 | 'indent' => $Line['indent'],
500 | 'pattern' => $pattern,
501 | 'element' => array(
502 | 'name' => $name,
503 | 'handler' => 'elements',
504 | ),
505 | );
506 |
507 | $Block['li'] = array(
508 | 'name' => 'li',
509 | 'handler' => 'li',
510 | 'text' => array(
511 | $matches[2],
512 | ),
513 | );
514 |
515 | $Block['element']['text'] []= & $Block['li'];
516 |
517 | return $Block;
518 | }
519 | }
520 |
521 | protected function blockListContinue($Line, array $Block)
522 | {
523 | if ($Block['indent'] === $Line['indent'] and preg_match('/^'.$Block['pattern'].'(?:[ ]+(.*)|$)/', $Line['text'], $matches))
524 | {
525 | if (isset($Block['interrupted']))
526 | {
527 | $Block['li']['text'] []= '';
528 |
529 | unset($Block['interrupted']);
530 | }
531 |
532 | unset($Block['li']);
533 |
534 | $text = isset($matches[1]) ? $matches[1] : '';
535 |
536 | $Block['li'] = array(
537 | 'name' => 'li',
538 | 'handler' => 'li',
539 | 'text' => array(
540 | $text,
541 | ),
542 | );
543 |
544 | $Block['element']['text'] []= & $Block['li'];
545 |
546 | return $Block;
547 | }
548 |
549 | if ($Line['text'][0] === '[' and $this->blockReference($Line))
550 | {
551 | return $Block;
552 | }
553 |
554 | if ( ! isset($Block['interrupted']))
555 | {
556 | $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']);
557 |
558 | $Block['li']['text'] []= $text;
559 |
560 | return $Block;
561 | }
562 |
563 | if ($Line['indent'] > 0)
564 | {
565 | $Block['li']['text'] []= '';
566 |
567 | $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']);
568 |
569 | $Block['li']['text'] []= $text;
570 |
571 | unset($Block['interrupted']);
572 |
573 | return $Block;
574 | }
575 | }
576 |
577 | #
578 | # Quote
579 |
580 | protected function blockQuote($Line)
581 | {
582 | if (preg_match('/^>[ ]?(.*)/', $Line['text'], $matches))
583 | {
584 | $Block = array(
585 | 'element' => array(
586 | 'name' => 'blockquote',
587 | 'handler' => 'lines',
588 | 'text' => (array) $matches[1],
589 | ),
590 | );
591 |
592 | return $Block;
593 | }
594 | }
595 |
596 | protected function blockQuoteContinue($Line, array $Block)
597 | {
598 | if ($Line['text'][0] === '>' and preg_match('/^>[ ]?(.*)/', $Line['text'], $matches))
599 | {
600 | if (isset($Block['interrupted']))
601 | {
602 | $Block['element']['text'] []= '';
603 |
604 | unset($Block['interrupted']);
605 | }
606 |
607 | $Block['element']['text'] []= $matches[1];
608 |
609 | return $Block;
610 | }
611 |
612 | if ( ! isset($Block['interrupted']))
613 | {
614 | $Block['element']['text'] []= $Line['text'];
615 |
616 | return $Block;
617 | }
618 | }
619 |
620 | #
621 | # Rule
622 |
623 | protected function blockRule($Line)
624 | {
625 | if (preg_match('/^(['.$Line['text'][0].'])([ ]*\1){2,}[ ]*$/', $Line['text']))
626 | {
627 | $Block = array(
628 | 'element' => array(
629 | 'name' => 'hr'
630 | ),
631 | );
632 |
633 | return $Block;
634 | }
635 | }
636 |
637 | #
638 | # Setext
639 |
640 | protected function blockSetextHeader($Line, array $Block = null)
641 | {
642 | if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted']))
643 | {
644 | return;
645 | }
646 |
647 | if (chop($Line['text'], $Line['text'][0]) === '')
648 | {
649 | $Block['element']['name'] = $Line['text'][0] === '=' ? 'h1' : 'h2';
650 |
651 | return $Block;
652 | }
653 | }
654 |
655 | #
656 | # Markup
657 |
658 | protected function blockMarkup($Line)
659 | {
660 | if ($this->markupEscaped)
661 | {
662 | return;
663 | }
664 |
665 | if (preg_match('/^<(\w*)(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*(\/)?>/', $Line['text'], $matches))
666 | {
667 | if (in_array($matches[1], $this->textLevelElements))
668 | {
669 | return;
670 | }
671 |
672 | $Block = array(
673 | 'name' => $matches[1],
674 | 'depth' => 0,
675 | 'markup' => $Line['text'],
676 | );
677 |
678 | $length = strlen($matches[0]);
679 |
680 | $remainder = substr($Line['text'], $length);
681 |
682 | if (trim($remainder) === '')
683 | {
684 | if (isset($matches[2]) or in_array($matches[1], $this->voidElements))
685 | {
686 | $Block['closed'] = true;
687 |
688 | $Block['void'] = true;
689 | }
690 | }
691 | else
692 | {
693 | if (isset($matches[2]) or in_array($matches[1], $this->voidElements))
694 | {
695 | return;
696 | }
697 |
698 | if (preg_match('/<\/'.$matches[1].'>[ ]*$/i', $remainder))
699 | {
700 | $Block['closed'] = true;
701 | }
702 | }
703 |
704 | return $Block;
705 | }
706 | }
707 |
708 | protected function blockMarkupContinue($Line, array $Block)
709 | {
710 | if (isset($Block['closed']))
711 | {
712 | return;
713 | }
714 |
715 | if (preg_match('/^<'.$Block['name'].'(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*>/i', $Line['text'])) # open
716 | {
717 | $Block['depth'] ++;
718 | }
719 |
720 | if (preg_match('/(.*?)<\/'.$Block['name'].'>[ ]*$/i', $Line['text'], $matches)) # close
721 | {
722 | if ($Block['depth'] > 0)
723 | {
724 | $Block['depth'] --;
725 | }
726 | else
727 | {
728 | $Block['closed'] = true;
729 | }
730 | }
731 |
732 | if (isset($Block['interrupted']))
733 | {
734 | $Block['markup'] .= "\n";
735 |
736 | unset($Block['interrupted']);
737 | }
738 |
739 | $Block['markup'] .= "\n".$Line['body'];
740 |
741 | return $Block;
742 | }
743 |
744 | #
745 | # Reference
746 |
747 | protected function blockReference($Line)
748 | {
749 | if (preg_match('/^\[(.+?)\]:[ ]*(\S+?)>?(?:[ ]+["\'(](.+)["\')])?[ ]*$/', $Line['text'], $matches))
750 | {
751 | $id = strtolower($matches[1]);
752 |
753 | $Data = array(
754 | 'url' => $matches[2],
755 | 'title' => null,
756 | );
757 |
758 | if (isset($matches[3]))
759 | {
760 | $Data['title'] = $matches[3];
761 | }
762 |
763 | $this->DefinitionData['Reference'][$id] = $Data;
764 |
765 | $Block = array(
766 | 'hidden' => true,
767 | );
768 |
769 | return $Block;
770 | }
771 | }
772 |
773 | #
774 | # Table
775 |
776 | protected function blockTable($Line, array $Block = null)
777 | {
778 | if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted']))
779 | {
780 | return;
781 | }
782 |
783 | if (strpos($Block['element']['text'], '|') !== false and chop($Line['text'], ' -:|') === '')
784 | {
785 | $alignments = array();
786 |
787 | $divider = $Line['text'];
788 |
789 | $divider = trim($divider);
790 | $divider = trim($divider, '|');
791 |
792 | $dividerCells = explode('|', $divider);
793 |
794 | foreach ($dividerCells as $dividerCell)
795 | {
796 | $dividerCell = trim($dividerCell);
797 |
798 | if ($dividerCell === '')
799 | {
800 | continue;
801 | }
802 |
803 | $alignment = null;
804 |
805 | if ($dividerCell[0] === ':')
806 | {
807 | $alignment = 'left';
808 | }
809 |
810 | if (substr($dividerCell, - 1) === ':')
811 | {
812 | $alignment = $alignment === 'left' ? 'center' : 'right';
813 | }
814 |
815 | $alignments []= $alignment;
816 | }
817 |
818 | # ~
819 |
820 | $HeaderElements = array();
821 |
822 | $header = $Block['element']['text'];
823 |
824 | $header = trim($header);
825 | $header = trim($header, '|');
826 |
827 | $headerCells = explode('|', $header);
828 |
829 | foreach ($headerCells as $index => $headerCell)
830 | {
831 | $headerCell = trim($headerCell);
832 |
833 | $HeaderElement = array(
834 | 'name' => 'th',
835 | 'text' => $headerCell,
836 | 'handler' => 'line',
837 | );
838 |
839 | if (isset($alignments[$index]))
840 | {
841 | $alignment = $alignments[$index];
842 |
843 | $HeaderElement['attributes'] = array(
844 | 'style' => 'text-align: '.$alignment.';',
845 | );
846 | }
847 |
848 | $HeaderElements []= $HeaderElement;
849 | }
850 |
851 | # ~
852 |
853 | $Block = array(
854 | 'alignments' => $alignments,
855 | 'identified' => true,
856 | 'element' => array(
857 | 'name' => 'table',
858 | 'handler' => 'elements',
859 | ),
860 | );
861 |
862 | $Block['element']['text'] []= array(
863 | 'name' => 'thead',
864 | 'handler' => 'elements',
865 | );
866 |
867 | $Block['element']['text'] []= array(
868 | 'name' => 'tbody',
869 | 'handler' => 'elements',
870 | 'text' => array(),
871 | );
872 |
873 | $Block['element']['text'][0]['text'] []= array(
874 | 'name' => 'tr',
875 | 'handler' => 'elements',
876 | 'text' => $HeaderElements,
877 | );
878 |
879 | return $Block;
880 | }
881 | }
882 |
883 | protected function blockTableContinue($Line, array $Block)
884 | {
885 | if (isset($Block['interrupted']))
886 | {
887 | return;
888 | }
889 |
890 | if ($Line['text'][0] === '|' or strpos($Line['text'], '|'))
891 | {
892 | $Elements = array();
893 |
894 | $row = $Line['text'];
895 |
896 | $row = trim($row);
897 | $row = trim($row, '|');
898 |
899 | preg_match_all('/(?:(\\\\[|])|[^|`]|`[^`]+`|`)+/', $row, $matches);
900 |
901 | foreach ($matches[0] as $index => $cell)
902 | {
903 | $cell = trim($cell);
904 |
905 | $Element = array(
906 | 'name' => 'td',
907 | 'handler' => 'line',
908 | 'text' => $cell,
909 | );
910 |
911 | if (isset($Block['alignments'][$index]))
912 | {
913 | $Element['attributes'] = array(
914 | 'style' => 'text-align: '.$Block['alignments'][$index].';',
915 | );
916 | }
917 |
918 | $Elements []= $Element;
919 | }
920 |
921 | $Element = array(
922 | 'name' => 'tr',
923 | 'handler' => 'elements',
924 | 'text' => $Elements,
925 | );
926 |
927 | $Block['element']['text'][1]['text'] []= $Element;
928 |
929 | return $Block;
930 | }
931 | }
932 |
933 | #
934 | # ~
935 | #
936 |
937 | protected function paragraph($Line)
938 | {
939 | $Block = array(
940 | 'element' => array(
941 | 'name' => 'p',
942 | 'text' => $Line['text'],
943 | 'handler' => 'line',
944 | ),
945 | );
946 |
947 | return $Block;
948 | }
949 |
950 | #
951 | # Inline Elements
952 | #
953 |
954 | protected $InlineTypes = array(
955 | '"' => array('SpecialCharacter'),
956 | '!' => array('Image'),
957 | '&' => array('SpecialCharacter'),
958 | '*' => array('Emphasis'),
959 | ':' => array('Url'),
960 | '<' => array('UrlTag', 'EmailTag', 'Markup', 'SpecialCharacter'),
961 | '>' => array('SpecialCharacter'),
962 | '[' => array('Link'),
963 | '_' => array('Emphasis'),
964 | '`' => array('Code'),
965 | '~' => array('Strikethrough'),
966 | '\\' => array('EscapeSequence'),
967 | );
968 |
969 | # ~
970 |
971 | protected $inlineMarkerList = '!"*_&[:<>`~\\';
972 |
973 | #
974 | # ~
975 | #
976 |
977 | public function line($text)
978 | {
979 | $markup = '';
980 |
981 | $unexaminedText = $text;
982 |
983 | $markerPosition = 0;
984 |
985 | while ($excerpt = strpbrk($unexaminedText, $this->inlineMarkerList))
986 | {
987 | $marker = $excerpt[0];
988 |
989 | $markerPosition += strpos($unexaminedText, $marker);
990 |
991 | $Excerpt = array('text' => $excerpt, 'context' => $text);
992 |
993 | foreach ($this->InlineTypes[$marker] as $inlineType)
994 | {
995 | $Inline = $this->{'inline'.$inlineType}($Excerpt);
996 |
997 | if ( ! isset($Inline))
998 | {
999 | continue;
1000 | }
1001 |
1002 | if (isset($Inline['position']) and $Inline['position'] > $markerPosition) # position is ahead of marker
1003 | {
1004 | continue;
1005 | }
1006 |
1007 | if ( ! isset($Inline['position']))
1008 | {
1009 | $Inline['position'] = $markerPosition;
1010 | }
1011 |
1012 | $unmarkedText = substr($text, 0, $Inline['position']);
1013 |
1014 | $markup .= $this->unmarkedText($unmarkedText);
1015 |
1016 | $markup .= isset($Inline['markup']) ? $Inline['markup'] : $this->element($Inline['element']);
1017 |
1018 | $text = substr($text, $Inline['position'] + $Inline['extent']);
1019 |
1020 | $unexaminedText = $text;
1021 |
1022 | $markerPosition = 0;
1023 |
1024 | continue 2;
1025 | }
1026 |
1027 | $unexaminedText = substr($excerpt, 1);
1028 |
1029 | $markerPosition ++;
1030 | }
1031 |
1032 | $markup .= $this->unmarkedText($text);
1033 |
1034 | return $markup;
1035 | }
1036 |
1037 | #
1038 | # ~
1039 | #
1040 |
1041 | protected function inlineCode($Excerpt)
1042 | {
1043 | $marker = $Excerpt['text'][0];
1044 |
1045 | if (preg_match('/^('.$marker.'+)[ ]*(.+?)[ ]*(? strlen($matches[0]),
1053 | 'element' => array(
1054 | 'name' => 'code',
1055 | 'text' => $text,
1056 | ),
1057 | );
1058 | }
1059 | }
1060 |
1061 | protected function inlineEmailTag($Excerpt)
1062 | {
1063 | if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<((mailto:)?\S+?@\S+?)>/i', $Excerpt['text'], $matches))
1064 | {
1065 | $url = $matches[1];
1066 |
1067 | if ( ! isset($matches[2]))
1068 | {
1069 | $url = 'mailto:' . $url;
1070 | }
1071 |
1072 | return array(
1073 | 'extent' => strlen($matches[0]),
1074 | 'element' => array(
1075 | 'name' => 'a',
1076 | 'text' => $matches[1],
1077 | 'attributes' => array(
1078 | 'href' => $url,
1079 | ),
1080 | ),
1081 | );
1082 | }
1083 | }
1084 |
1085 | protected function inlineEmphasis($Excerpt)
1086 | {
1087 | if ( ! isset($Excerpt['text'][1]))
1088 | {
1089 | return;
1090 | }
1091 |
1092 | $marker = $Excerpt['text'][0];
1093 |
1094 | if ($Excerpt['text'][1] === $marker and preg_match($this->StrongRegex[$marker], $Excerpt['text'], $matches))
1095 | {
1096 | $emphasis = 'strong';
1097 | }
1098 | elseif (preg_match($this->EmRegex[$marker], $Excerpt['text'], $matches))
1099 | {
1100 | $emphasis = 'em';
1101 | }
1102 | else
1103 | {
1104 | return;
1105 | }
1106 |
1107 | return array(
1108 | 'extent' => strlen($matches[0]),
1109 | 'element' => array(
1110 | 'name' => $emphasis,
1111 | 'handler' => 'line',
1112 | 'text' => $matches[1],
1113 | ),
1114 | );
1115 | }
1116 |
1117 | protected function inlineEscapeSequence($Excerpt)
1118 | {
1119 | if (isset($Excerpt['text'][1]) and in_array($Excerpt['text'][1], $this->specialCharacters))
1120 | {
1121 | return array(
1122 | 'markup' => $Excerpt['text'][1],
1123 | 'extent' => 2,
1124 | );
1125 | }
1126 | }
1127 |
1128 | protected function inlineImage($Excerpt)
1129 | {
1130 | if ( ! isset($Excerpt['text'][1]) or $Excerpt['text'][1] !== '[')
1131 | {
1132 | return;
1133 | }
1134 |
1135 | $Excerpt['text']= substr($Excerpt['text'], 1);
1136 |
1137 | $Link = $this->inlineLink($Excerpt);
1138 |
1139 | if ($Link === null)
1140 | {
1141 | return;
1142 | }
1143 |
1144 | $Inline = array(
1145 | 'extent' => $Link['extent'] + 1,
1146 | 'element' => array(
1147 | 'name' => 'img',
1148 | 'attributes' => array(
1149 | 'src' => $Link['element']['attributes']['href'],
1150 | 'alt' => $Link['element']['text'],
1151 | 'data-action' => 'zoom',
1152 | 'style' => 'max-width:100%',
1153 | ),
1154 | ),
1155 | );
1156 |
1157 | $Inline['element']['attributes'] += $Link['element']['attributes'];
1158 |
1159 | unset($Inline['element']['attributes']['href']);
1160 |
1161 | return $Inline;
1162 | }
1163 |
1164 | protected function inlineLink($Excerpt)
1165 | {
1166 | $Element = array(
1167 | 'name' => 'a',
1168 | 'handler' => 'line',
1169 | 'text' => null,
1170 | 'attributes' => array(
1171 | 'href' => null,
1172 | 'title' => null,
1173 | ),
1174 | );
1175 |
1176 | $extent = 0;
1177 |
1178 | $remainder = $Excerpt['text'];
1179 |
1180 | if (preg_match('/\[((?:[^][]|(?R))*)\]/', $remainder, $matches))
1181 | {
1182 | $Element['text'] = $matches[1];
1183 |
1184 | $extent += strlen($matches[0]);
1185 |
1186 | $remainder = substr($remainder, $extent);
1187 | }
1188 | else
1189 | {
1190 | return;
1191 | }
1192 |
1193 | if (preg_match('/^[(]((?:[^ ()]|[(][^ )]+[)])+)(?:[ ]+("[^"]*"|\'[^\']*\'))?[)]/', $remainder, $matches))
1194 | {
1195 | $Element['attributes']['href'] = $matches[1];
1196 |
1197 | if (isset($matches[2]))
1198 | {
1199 | $Element['attributes']['title'] = substr($matches[2], 1, - 1);
1200 | }
1201 |
1202 | $extent += strlen($matches[0]);
1203 | }
1204 | else
1205 | {
1206 | if (preg_match('/^\s*\[(.*?)\]/', $remainder, $matches))
1207 | {
1208 | $definition = strlen($matches[1]) ? $matches[1] : $Element['text'];
1209 | $definition = strtolower($definition);
1210 |
1211 | $extent += strlen($matches[0]);
1212 | }
1213 | else
1214 | {
1215 | $definition = strtolower($Element['text']);
1216 | }
1217 |
1218 | if ( ! isset($this->DefinitionData['Reference'][$definition]))
1219 | {
1220 | return;
1221 | }
1222 |
1223 | $Definition = $this->DefinitionData['Reference'][$definition];
1224 |
1225 | $Element['attributes']['href'] = $Definition['url'];
1226 | $Element['attributes']['title'] = $Definition['title'];
1227 | }
1228 |
1229 | $Element['attributes']['href'] = str_replace(array('&', '<'), array('&', '<'), $Element['attributes']['href']);
1230 |
1231 | return array(
1232 | 'extent' => $extent,
1233 | 'element' => $Element,
1234 | );
1235 | }
1236 |
1237 | protected function inlineMarkup($Excerpt)
1238 | {
1239 | if ($this->markupEscaped or strpos($Excerpt['text'], '>') === false)
1240 | {
1241 | return;
1242 | }
1243 |
1244 | if ($Excerpt['text'][1] === '/' and preg_match('/^<\/\w*[ ]*>/s', $Excerpt['text'], $matches))
1245 | {
1246 | return array(
1247 | 'markup' => $matches[0],
1248 | 'extent' => strlen($matches[0]),
1249 | );
1250 | }
1251 |
1252 | if ($Excerpt['text'][1] === '!' and preg_match('/^/s', $Excerpt['text'], $matches))
1253 | {
1254 | return array(
1255 | 'markup' => $matches[0],
1256 | 'extent' => strlen($matches[0]),
1257 | );
1258 | }
1259 |
1260 | if ($Excerpt['text'][1] !== ' ' and preg_match('/^<\w*(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*\/?>/s', $Excerpt['text'], $matches))
1261 | {
1262 | return array(
1263 | 'markup' => $matches[0],
1264 | 'extent' => strlen($matches[0]),
1265 | );
1266 | }
1267 | }
1268 |
1269 | protected function inlineSpecialCharacter($Excerpt)
1270 | {
1271 | if ($Excerpt['text'][0] === '&' and ! preg_match('/^?\w+;/', $Excerpt['text']))
1272 | {
1273 | return array(
1274 | 'markup' => '&',
1275 | 'extent' => 1,
1276 | );
1277 | }
1278 |
1279 | $SpecialCharacter = array('>' => 'gt', '<' => 'lt', '"' => 'quot');
1280 |
1281 | if (isset($SpecialCharacter[$Excerpt['text'][0]]))
1282 | {
1283 | return array(
1284 | 'markup' => '&'.$SpecialCharacter[$Excerpt['text'][0]].';',
1285 | 'extent' => 1,
1286 | );
1287 | }
1288 | }
1289 |
1290 | protected function inlineStrikethrough($Excerpt)
1291 | {
1292 | if ( ! isset($Excerpt['text'][1]))
1293 | {
1294 | return;
1295 | }
1296 |
1297 | if ($Excerpt['text'][1] === '~' and preg_match('/^~~(?=\S)(.+?)(?<=\S)~~/', $Excerpt['text'], $matches))
1298 | {
1299 | return array(
1300 | 'extent' => strlen($matches[0]),
1301 | 'element' => array(
1302 | 'name' => 'del',
1303 | 'text' => $matches[1],
1304 | 'handler' => 'line',
1305 | ),
1306 | );
1307 | }
1308 | }
1309 |
1310 | protected function inlineUrl($Excerpt)
1311 | {
1312 | if ($this->urlsLinked !== true or ! isset($Excerpt['text'][2]) or $Excerpt['text'][2] !== '/')
1313 | {
1314 | return;
1315 | }
1316 |
1317 | if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE))
1318 | {
1319 | $Inline = array(
1320 | 'extent' => strlen($matches[0][0]),
1321 | 'position' => $matches[0][1],
1322 | 'element' => array(
1323 | 'name' => 'a',
1324 | 'text' => $matches[0][0],
1325 | 'attributes' => array(
1326 | 'href' => $matches[0][0],
1327 | ),
1328 | ),
1329 | );
1330 |
1331 | return $Inline;
1332 | }
1333 | }
1334 |
1335 | protected function inlineUrlTag($Excerpt)
1336 | {
1337 | if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w+:\/{2}[^ >]+)>/i', $Excerpt['text'], $matches))
1338 | {
1339 | $url = str_replace(array('&', '<'), array('&', '<'), $matches[1]);
1340 |
1341 | return array(
1342 | 'extent' => strlen($matches[0]),
1343 | 'element' => array(
1344 | 'name' => 'a',
1345 | 'text' => $url,
1346 | 'attributes' => array(
1347 | 'href' => $url,
1348 | ),
1349 | ),
1350 | );
1351 | }
1352 | }
1353 |
1354 | # ~
1355 |
1356 | protected function unmarkedText($text)
1357 | {
1358 | if ($this->breaksEnabled)
1359 | {
1360 | $text = preg_replace('/[ ]*\n/', "
\n", $text);
1361 | }
1362 | else
1363 | {
1364 | $text = preg_replace('/(?:[ ][ ]+|[ ]*\\\\)\n/', "
\n", $text);
1365 | $text = str_replace(" \n", "\n", $text);
1366 | }
1367 |
1368 | return $text;
1369 | }
1370 |
1371 | #
1372 | # Handlers
1373 | #
1374 |
1375 | protected function element(array $Element)
1376 | {
1377 | $markup = '<'.$Element['name'];
1378 |
1379 | if (isset($Element['attributes']))
1380 | {
1381 | foreach ($Element['attributes'] as $name => $value)
1382 | {
1383 | if ($value === null)
1384 | {
1385 | continue;
1386 | }
1387 |
1388 | $markup .= ' '.$name.'="'.$value.'"';
1389 | }
1390 | }
1391 |
1392 | if (isset($Element['text']))
1393 | {
1394 | $markup .= '>';
1395 |
1396 | if (isset($Element['handler']))
1397 | {
1398 | $markup .= $this->{$Element['handler']}($Element['text']);
1399 | }
1400 | else
1401 | {
1402 | $markup .= $Element['text'];
1403 | }
1404 |
1405 | $markup .= ''.$Element['name'].'>';
1406 | }
1407 | else
1408 | {
1409 | $markup .= ' />';
1410 | }
1411 |
1412 | return $markup;
1413 | }
1414 |
1415 | protected function elements(array $Elements)
1416 | {
1417 | $markup = '';
1418 |
1419 | foreach ($Elements as $Element)
1420 | {
1421 | $markup .= "\n" . $this->element($Element);
1422 | }
1423 |
1424 | $markup .= "\n";
1425 |
1426 | return $markup;
1427 | }
1428 |
1429 | # ~
1430 |
1431 | protected function li($lines)
1432 | {
1433 | $markup = $this->lines($lines);
1434 |
1435 | $trimmedMarkup = trim($markup);
1436 |
1437 | if ( ! in_array('', $lines) and substr($trimmedMarkup, 0, 3) === '')
1438 | {
1439 | $markup = $trimmedMarkup;
1440 | $markup = substr($markup, 3);
1441 |
1442 | $position = strpos($markup, "
");
1443 |
1444 | $markup = substr_replace($markup, '', $position, 4);
1445 | }
1446 |
1447 | return $markup;
1448 | }
1449 |
1450 | #
1451 | # Deprecated Methods
1452 | #
1453 |
1454 | function parse($text)
1455 | {
1456 | $markup = $this->text($text);
1457 |
1458 | return $markup;
1459 | }
1460 |
1461 | #
1462 | # Static Methods
1463 | #
1464 |
1465 | static function instance($name = 'default')
1466 | {
1467 | if (isset(self::$instances[$name]))
1468 | {
1469 | return self::$instances[$name];
1470 | }
1471 |
1472 | $instance = new self();
1473 |
1474 | self::$instances[$name] = $instance;
1475 |
1476 | return $instance;
1477 | }
1478 |
1479 | private static $instances = array();
1480 |
1481 | #
1482 | # Fields
1483 | #
1484 |
1485 | protected $DefinitionData;
1486 |
1487 | #
1488 | # Read-Only
1489 |
1490 | protected $specialCharacters = array(
1491 | '\\', '`', '*', '_', '{', '}', '[', ']', '(', ')', '>', '#', '+', '-', '.', '!', '|',
1492 | );
1493 |
1494 | protected $StrongRegex = array(
1495 | '*' => '/^[*]{2}((?:\\\\\*|[^*]|[*][^*]*[*])+?)[*]{2}(?![*])/s',
1496 | '_' => '/^__((?:\\\\_|[^_]|_[^_]*_)+?)__(?!_)/us',
1497 | );
1498 |
1499 | protected $EmRegex = array(
1500 | '*' => '/^[*]((?:\\\\\*|[^*]|[*][*][^*]+?[*][*])+?)[*](?![*])/s',
1501 | '_' => '/^_((?:\\\\_|[^_]|__[^_]*__)+?)_(?!_)\b/us',
1502 | );
1503 |
1504 | protected $regexHtmlAttribute = '[a-zA-Z_:][\w:.-]*(?:\s*=\s*(?:[^"\'=<>`\s]+|"[^"]*"|\'[^\']*\'))?';
1505 |
1506 | protected $voidElements = array(
1507 | 'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source',
1508 | );
1509 |
1510 | protected $textLevelElements = array(
1511 | 'a', 'br', 'bdo', 'abbr', 'blink', 'nextid', 'acronym', 'basefont',
1512 | 'b', 'em', 'big', 'cite', 'small', 'spacer', 'listing',
1513 | 'i', 'rp', 'del', 'code', 'strike', 'marquee',
1514 | 'q', 'rt', 'ins', 'font', 'strong',
1515 | 's', 'tt', 'sub', 'mark',
1516 | 'u', 'xm', 'sup', 'nobr',
1517 | 'var', 'ruby',
1518 | 'wbr', 'span',
1519 | 'time',
1520 | );
1521 | }
--------------------------------------------------------------------------------
/src/config/editor.php:
--------------------------------------------------------------------------------
1 | '890px',
6 | 'uploadUrl'=>'home/upload',
7 | /*
8 | * 在添加链接的时候可以给定一个ajax链接,这样可以方便的添加在系统中的文章
9 | * 服务器返回的数据格式为:{'title':'url','title2':'url2'}
10 | */
11 | // 'ajaxTopicSearchUrl' => 'home/ajax-search-topics'
12 | ];
--------------------------------------------------------------------------------
/src/config/editor/css/editor.css:
--------------------------------------------------------------------------------
1 | .editor {
2 | position: relative;
3 | z-index: 1;
4 | margin-bottom: 20px;
5 | min-height: 300px; }
6 | .editor textarea {
7 | resize: none; }
8 | .editor .text-muted {
9 | cursor: default;
10 | text-decoration: none; }
11 | .editor .text-muted:hover {
12 | cursor: default;
13 | color: #999; }
14 | .editor__input {
15 | border: none;
16 | width: 100%;
17 | resize: none;
18 | padding: 10px;
19 | margin-bottom: -5px;
20 | border-radius: 5px; }
21 | .editor__resize {
22 | position: absolute;
23 | width: 100px;
24 | height: 4px;
25 | left: 50%;
26 | margin-left: -50px;
27 | margin-top: 2px;
28 | border-top: 1px solid #ddd;
29 | border-bottom: 1px solid #ddd;
30 | text-indent: -9999px;
31 | cursor: row-resize; }
32 |
33 | .editor__menu {
34 | list-style: none;
35 | margin: 0;
36 | padding: 0 5px;
37 | border: 1px solid #ddd;
38 | border-bottom: none;
39 | background-color: #f6f6f6;
40 | border-radius: 2px 2px 0 0;
41 | position: relative;
42 | z-index: 2; }
43 | .editor__menu li {
44 | float: left;
45 | margin: 0 2px;
46 | vertical-align: text-top; }
47 | .editor__menu a {
48 | cursor: pointer;
49 | display: block;
50 | border: 5px solid #f6f6f6;
51 | box-sizing: content-box;
52 | width: 20px;
53 | height: 20px;
54 | background-repeat: no-repeat;
55 | background-size: 380px 60px;
56 | background-image: url(../images/editor@2x.png);
57 | text-indent: -9999px; }
58 | .editor__menu a.muted,
59 | .editor__menu a.muted:hover {
60 | background-position-y: -20px;
61 | background-color: #f6f6f6;
62 | border-color: #f6f6f6;
63 | cursor: default; }
64 | .editor__menu a:hover,
65 | .editor__menu a.active {
66 | border-color: #fff;
67 | background-color: #fff;
68 | background-position-y: -40px;
69 | text-decoration: none; }
70 | .editor__menu .active {
71 | color: #999; }
72 | .editor__menu--bold {
73 | background-position: -1px 0px; }
74 | .editor__menu--italic {
75 | background-position: -21px 0px; }
76 | .editor__menu--link {
77 | background-position: -40px 0px; }
78 | .editor__menu--quote {
79 | background-position: -60px 0px; }
80 | .editor__menu--code {
81 | background-position: -80px 0px; }
82 | .editor__menu--img {
83 | background-position: -100px 0px; }
84 | .editor__menu--ol {
85 | background-position: -120px 0px; }
86 | .editor__menu--ul {
87 | background-position: -140px 0px; }
88 | .editor__menu--title {
89 | background-position: -160px 0px; }
90 | .editor__menu--hr {
91 | background-position: -180px 0px; }
92 | .editor__menu--undo {
93 | background-position: -200px 0px; }
94 | .editor__menu--redo {
95 | background-position: -220px 0px; }
96 | .editor__menu--zen {
97 | background-position: -240px 0px; }
98 | .editor__menu--unzen {
99 | background-position: -260px 0px; }
100 | .editor__menu--two {
101 | background-position: -280px 0px; }
102 | .editor__menu--help {
103 | background-position: -300px 0px; }
104 | .editor__menu .editor__menu--divider {
105 | margin: 5px 4px;
106 | width: 0;
107 | text-indent: -9999px;
108 | height: 20px;
109 | padding-left: 0;
110 | padding-right: 0;
111 | border-right: 1px solid #ddd; }
112 | .editor__menu--edit {
113 | background-position: -320px 0px; }
114 | .editor__menu--live {
115 | background-position: -340px 0px; }
116 | .editor__menu--preview {
117 | background-position: -360px 0px; }
118 |
119 | .editor-help {
120 | border: 1px solid #ddd;
121 | border-bottom: none;
122 | background-color: #faf2cc;
123 | font-size: 13px; }
124 | .editor-help .nav-tabs {
125 | border-bottom: none;
126 | background-color: #fcf8e3; }
127 | .editor-help .nav > li {
128 | margin: 0; }
129 | .editor-help .nav > li > a {
130 | margin: 0;
131 | padding: 6px 10px;
132 | border: none;
133 | color: #8a6d3b;
134 | border-radius: 0; }
135 | .editor-help .nav > li.active > a,
136 | .editor-help .nav > li > a:hover {
137 | border: none;
138 | background-color: #faf2cc;
139 | color: #8a6d3b;
140 | cursor: pointer; }
141 | .editor-help .nav > li.active > a {
142 | font-weight: bold; }
143 |
144 | .editor-help-content {
145 | padding: 10px; }
146 | .editor-help-content pre {
147 | padding: 5px 8px;
148 | border: none;
149 | background-color: #fcf8e3;
150 | font-size: 12px; }
151 | .editor-help-content code {
152 | white-space: normal; }
153 |
154 | .widget-editor__wrap {
155 | background: #F6F6F6;
156 | border-top: 1px solid #DDD; }
157 |
158 | .widget-editor .widget-editor__help {
159 | margin-top: 40px; }
160 |
161 | .CodeMirror {
162 | height: auto;
163 | /*min-height: 420px;*/
164 | padding: 0; }
165 | .CodeMirror .CodeMirror-scroll {
166 | height: 100%;
167 | min-height: 420px; }
168 | .CodeMirror .CodeMirror-cursor {
169 | height: 20px !important; }
170 |
171 | /* DEFAULT THEME */
172 | .cm-s-paper .cm-keyword {
173 | color: #555; }
174 |
175 | .cm-s-paper .cm-atom {
176 | color: #7f8c8d; }
177 |
178 | .cm-s-paper .cm-number {
179 | color: #7f8c8d; }
180 |
181 | .cm-s-paper .cm-def {
182 | color: #00f; }
183 |
184 | .cm-s-paper .cm-variable {
185 | color: black; }
186 |
187 | .cm-s-paper .cm-variable-2 {
188 | color: #555; }
189 |
190 | .cm-s-paper .cm-variable-3 {
191 | color: #085; }
192 |
193 | .cm-s-paper .cm-property {
194 | color: black; }
195 |
196 | .cm-s-paper .cm-operator {
197 | color: black; }
198 |
199 | .cm-s-paper .cm-comment {
200 | color: #959595; }
201 |
202 | .cm-s-paper .cm-string {
203 | color: #7f8c8d; }
204 |
205 | .cm-s-paper .cm-string-2 {
206 | color: #f50; }
207 |
208 | .cm-s-paper .cm-meta {
209 | color: #555; }
210 |
211 | .cm-s-paper .cm-error {
212 | color: #f00; }
213 |
214 | .cm-s-paper .cm-qualifier {
215 | color: #555; }
216 |
217 | .cm-s-paper .cm-builtin {
218 | color: #555; }
219 |
220 | .cm-s-paper .cm-bracket {
221 | color: #997; }
222 |
223 | .cm-s-paper .cm-tag {
224 | color: #7f8c8d; }
225 |
226 | .cm-s-paper .cm-attribute {
227 | color: #7f8c8d; }
228 |
229 | .cm-s-paper .cm-header {
230 | color: #000; }
231 |
232 | .cm-s-paper .cm-quote {
233 | color: #888; }
234 |
235 | .cm-s-paper .cm-hr {
236 | color: #999; }
237 |
238 | .cm-s-paper .cm-link {
239 | color: #7f8c8d; }
240 |
241 | .cm-negative {
242 | color: #d44; }
243 |
244 | .cm-positive {
245 | color: #292; }
246 |
247 | .cm-header, .cm-strong {
248 | font-weight: bold; }
249 |
250 | .cm-em {
251 | font-style: italic; }
252 |
253 | .cm-link {
254 | text-decoration: underline; }
255 |
256 | .cm-invalidchar {
257 | color: #f00; }
258 |
259 | div.CodeMirror span.CodeMirror-matchingbracket {
260 | color: #0f0; }
261 |
262 | div.CodeMirror span.CodeMirror-nonmatchingbracket {
263 | color: #f22; }
264 |
265 | .CodeMirror-focused {
266 | border-color: #66afe9;
267 | outline: 0;
268 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); }
269 |
270 | :-webkit-full-screen {
271 | background: #f9f9f5;
272 | padding: 0.5em 1em;
273 | width: 100%;
274 | height: 100%; }
275 |
276 | :-moz-full-screen {
277 | padding: 0.5em 1em;
278 | background: #f9f9f5;
279 | width: 100%;
280 | height: 100%; }
281 |
282 | .editor-preview {
283 | position: absolute;
284 | padding: 20px;
285 | background-color: #f6f6f6;
286 | width: 100%;
287 | height: 100%;
288 | top: 0;
289 | left: 100%;
290 | z-index: 999;
291 | overflow: auto;
292 | overflow-x: hidden;
293 | -webkit-transition: left 0.1s ease;
294 | -moz-transition: left 0.1s ease;
295 | -ms-transition: left 0.1s ease;
296 | transition: left 0.1s ease; }
297 | .editor-preview code, .editor-preview pre, .editor-preview kbd {
298 | background-color: #eee !important; }
299 |
300 | .editor-preview-active {
301 | left: 0; }
302 |
303 | .editor-preview-active.onlive {
304 | left: 50%;
305 | width: 50%; }
306 |
307 | .editor-preview > p {
308 | margin-top: 0; }
309 |
310 | .editor-preview pre.hljs {
311 | padding: 10px;
312 | }
313 |
314 | .widget-upload {
315 | position: relative;
316 | }
317 | .widget-upload .widget-upload__file {
318 | position: absolute;
319 | opacity: 0;
320 | width: 85%;
321 | height: 100%;
322 | z-index: 10;
323 | cursor: pointer;
324 | }
325 |
326 | input.loading {
327 | background: url(../images/loader.gif) no-repeat right center;
328 | }
329 |
--------------------------------------------------------------------------------
/src/config/editor/css/editor.css.map:
--------------------------------------------------------------------------------
1 | {
2 | "version": 3,
3 | "mappings": "AACQ,oDAAyC;AAEjD,OAAQ;EACN,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,CAAC;EACV,aAAa,EAAE,IAAI;EACnB,UAAU,EAAE,KAAK;EACjB,gBAAS;IACP,MAAM,EAAE,IAAI;EAEd,mBAAY;IACR,MAAM,EAAE,OAAO;IACf,eAAe,EAAE,IAAI;IACrB,yBAAQ;MACN,MAAM,EAAE,OAAO;MACf,KAAK,EAAE,IAAI;EAGjB,cAAS;IACP,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;IACZ,OAAO,EAAE,IAAI;IACb,aAAa,EAAE,IAAI;IACnB,aAAa,EAAE,GAAG;EAEpB,eAAU;IACR,QAAQ,EAAE,QAAQ;IAClB,KAAK,EAAE,KAAK;IACZ,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,GAAG;IACT,WAAW,EAAE,KAAK;IAClB,UAAU,EAAE,GAAG;IACf,UAAU,EAAE,cAAc;IAC1B,aAAa,EAAE,cAAc;IAC7B,WAAW,EAAE,OAAO;IACpB,MAAM,EAAE,UAAU;;AAKtB,aAAc;EACZ,UAAU,EAAE,IAAI;EAChB,MAAM,EAAE,CAAC;EACT,OAAO,EAAE,KAAK;EACd,MAAM,EAAE,cAAc;EACtB,aAAa,EAAE,IAAI;EACnB,gBAAgB,EAAE,OAAO;EACzB,aAAa,EAAE,WAAW;EAC1B,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,CAAC;EACV,gBAAG;IACD,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,KAAK;IACb,cAAc,EAAE,QAAQ;EAE1B,eAAE;IACA,MAAM,EAAE,OAAO;IACf,OAAO,EAAE,KAAK;IACd,MAAM,EAAE,iBAAiB;IACzB,UAAU,EAAE,WAAW;IACvB,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;IACZ,iBAAiB,EAAE,SAAS;IAC5B,eAAe,EAAE,UAAU;IAC3B,gBAAgB,EAAE,gCAAgC;IAClD,WAAW,EAAE,OAAO;EAGtB;6BACc;IACZ,qBAAqB,EAAE,KAAK;IAC5B,gBAAgB,EAAE,OAAO;IACzB,YAAY,EAAE,OAAO;IACrB,MAAM,EAAE,OAAO;EAEjB;wBACS;IACP,YAAY,EAAE,IAAI;IAClB,gBAAgB,EAAE,IAAI;IACtB,qBAAqB,EAAE,KAAK;IAC5B,eAAe,EAAE,IAAI;EAEvB,qBAAQ;IACN,KAAK,EAAE,IAAI;EAEb,mBAAQ;IACN,mBAAmB,EAAE,QAAQ;EAE/B,qBAAU;IACR,mBAAmB,EAAE,SAAS;EAEhC,mBAAQ;IACN,mBAAmB,EAAE,SAAS;EAEhC,oBAAS;IACP,mBAAmB,EAAE,SAAS;EAEhC,mBAAQ;IACN,mBAAmB,EAAE,SAAS;EAEhC,kBAAO;IACL,mBAAmB,EAAE,UAAU;EAEjC,iBAAM;IACJ,mBAAmB,EAAE,UAAU;EAEjC,iBAAM;IACJ,mBAAmB,EAAE,UAAU;EAEjC,oBAAS;IACP,mBAAmB,EAAE,UAAU;EAEjC,iBAAM;IACJ,mBAAmB,EAAE,UAAU;EAEjC,mBAAQ;IACN,mBAAmB,EAAE,UAAU;EAEjC,mBAAQ;IACN,mBAAmB,EAAE,UAAU;EAEjC,kBAAO;IACL,mBAAmB,EAAE,UAAU;EAEjC,oBAAS;IACP,mBAAmB,EAAE,UAAU;EAEjC,kBAAO;IACL,mBAAmB,EAAE,UAAU;EAEjC,mBAAQ;IACN,mBAAmB,EAAE,UAAU;EAEjC,oCAAuB;IACrB,MAAM,EAAE,OAAO;IACf,KAAK,EAAE,CAAC;IACR,WAAW,EAAE,OAAO;IACpB,MAAM,EAAE,IAAI;IACZ,YAAY,EAAE,CAAC;IACf,aAAa,EAAE,CAAC;IAChB,YAAY,EAAE,cAAc;EAE9B,mBAAQ;IACN,mBAAmB,EAAE,UAAU;EAEjC,mBAAQ;IACN,mBAAmB,EAAE,UAAU;EAEjC,sBAAW;IACT,mBAAmB,EAAE,UAAU;;AAKnC,YAAa;EACX,MAAM,EAAE,cAAc;EACtB,aAAa,EAAE,IAAI;EACnB,gBAAgB,EAAE,OAAmB;EACrC,SAAS,EAAE,IAAI;EACf,sBAAU;IACR,aAAa,EAAE,IAAI;IACnB,gBAAgB,EAAE,OAAO;EAE3B,sBAAU;IACR,MAAM,EAAE,CAAC;EAEX,0BAAc;IACZ,MAAM,EAAE,CAAC;IACT,OAAO,EAAE,QAAQ;IACjB,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,OAAO;IACd,aAAa,EAAE,CAAC;EAElB;kCACqB;IACnB,MAAM,EAAE,IAAI;IACZ,gBAAgB,EAAE,OAAmB;IACrC,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,OAAO;EAEjB,iCAAqB;IACnB,WAAW,EAAE,IAAI;;AAGrB,oBAAqB;EACnB,OAAO,EAAE,IAAI;EACb,wBAAI;IACF,OAAO,EAAE,OAAO;IAChB,MAAM,EAAE,IAAI;IACZ,gBAAgB,EAAE,OAAO;IACzB,SAAS,EAAE,IAAI;EAEjB,yBAAK;IACH,WAAW,EAAE,MAAM;;AAKvB,oBAAqB;EACnB,UAAU,EAAE,OAAO;EACnB,UAAU,EAAE,cAAc;;AAG1B,mCAAqB;EACnB,UAAU,EAAE,IAAI;;AAIpB,WAAY;EACV,MAAM,EAAE,IAAI;EACZ,UAAU,EAAE,KAAK;EACjB,OAAO,EAAE,CAAC;EACV,8BAAmB;IACjB,MAAM,EAAE,IAAI;IACZ,UAAU,EAAE,KAAK;EAEnB,8BAAmB;IACjB,MAAM,EAAE,eAAe;;;AAO3B,uBAAwB;EAAC,KAAK,EAAE,IAAI;;AACpC,oBAAqB;EAAC,KAAK,EAAE,OAAO;;AACpC,sBAAuB;EAAC,KAAK,EAAE,OAAO;;AACtC,mBAAoB;EAAC,KAAK,EAAE,IAAI;;AAChC,wBAAyB;EAAC,KAAK,EAAE,KAAK;;AACtC,0BAA2B;EAAC,KAAK,EAAE,IAAI;;AACvC,0BAA2B;EAAC,KAAK,EAAE,IAAI;;AACvC,wBAAyB;EAAC,KAAK,EAAE,KAAK;;AACtC,wBAAyB;EAAC,KAAK,EAAE,KAAK;;AACtC,uBAAwB;EAAC,KAAK,EAAE,OAAO;;AACvC,sBAAuB;EAAC,KAAK,EAAE,OAAO;;AACtC,wBAAyB;EAAC,KAAK,EAAE,IAAI;;AACrC,oBAAqB;EAAC,KAAK,EAAE,IAAI;;AACjC,qBAAsB;EAAC,KAAK,EAAE,IAAI;;AAClC,yBAA0B;EAAC,KAAK,EAAE,IAAI;;AACtC,uBAAwB;EAAC,KAAK,EAAE,IAAI;;AACpC,uBAAwB;EAAC,KAAK,EAAE,IAAI;;AACpC,mBAAoB;EAAC,KAAK,EAAE,OAAO;;AACnC,yBAA0B;EAAC,KAAK,EAAE,OAAO;;AACzC,sBAAuB;EAAC,KAAK,EAAE,IAAI;;AACnC,qBAAsB;EAAC,KAAK,EAAE,IAAI;;AAClC,kBAAmB;EAAC,KAAK,EAAE,IAAI;;AAC/B,oBAAqB;EAAC,KAAK,EAAE,OAAO;;AAEpC,YAAa;EAAC,KAAK,EAAE,IAAI;;AACzB,YAAa;EAAC,KAAK,EAAE,IAAI;;AACzB,sBAAuB;EAAC,WAAW,EAAE,IAAI;;AACzC,MAAO;EAAC,UAAU,EAAE,MAAM;;AAC1B,QAAS;EAAC,eAAe,EAAE,SAAS;;AAEpC,eAAgB;EAAC,KAAK,EAAE,IAAI;;AAE5B,8CAA+C;EAAC,KAAK,EAAE,IAAI;;AAC3D,iDAAkD;EAAC,KAAK,EAAE,IAAI;;AAE9D,mBAAoB;EAElB,YAAY,EAAE,OAAO;EACrB,OAAO,EAAE,CAAC;EACV,UAAU,EAAE,oCAAgC;;AAG9C,oBAAqB;EACnB,UAAU,EAAE,OAAO;EACnB,OAAO,EAAE,SAAS;EAClB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;;AAEd,iBAAkB;EAChB,OAAO,EAAE,SAAS;EAClB,UAAU,EAAE,OAAO;EACnB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;;AAGd,eAAgB;EACd,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,IAAI;EACb,gBAAgB,EAAE,OAAO;EACzB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,GAAG,EAAE,CAAC;EACN,IAAI,EAAE,IAAI;EACV,OAAO,EAAE,GAAG;EACZ,QAAQ,EAAE,IAAI;EACd,UAAU,EAAE,MAAM;EAClB,kBAAkB,EAAE,cAAc;EAClC,eAAe,EAAE,cAAc;EAC/B,cAAc,EAAE,cAAc;EAC9B,UAAU,EAAE,cAAc;EAC1B,8DAAe;IACb,gBAAgB,EAAE,eAAe;;AAGrC,sBAAuB;EAErB,IAAI,EAAE,CAAC;;AAET,6BAA8B;EAC5B,IAAI,EAAE,GAAG;EACT,KAAK,EAAE,GAAG;;AAEZ,mBAAoB;EAClB,UAAU,EAAE,CAAC",
4 | "sources": ["editor.scss"],
5 | "names": [],
6 | "file": "editor.css"
7 | }
8 |
--------------------------------------------------------------------------------
/src/config/editor/css/pygment_trac.css:
--------------------------------------------------------------------------------
1 | .highlight { background: #ffffff; }
2 | .highlight .c { color: #999988; font-style: italic } /* Comment */
3 | .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
4 | .highlight .k { font-weight: bold } /* Keyword */
5 | .highlight .o { font-weight: bold } /* Operator */
6 | .highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
7 | .highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
8 | .highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
9 | .highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
10 | .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
11 | .highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
12 | .highlight .ge { font-style: italic } /* Generic.Emph */
13 | .highlight .gr { color: #aa0000 } /* Generic.Error */
14 | .highlight .gh { color: #999999 } /* Generic.Heading */
15 | .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
16 | .highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
17 | .highlight .go { color: #888888 } /* Generic.Output */
18 | .highlight .gp { color: #555555 } /* Generic.Prompt */
19 | .highlight .gs { font-weight: bold } /* Generic.Strong */
20 | .highlight .gu { color: #800080; font-weight: bold; } /* Generic.Subheading */
21 | .highlight .gt { color: #aa0000 } /* Generic.Traceback */
22 | .highlight .kc { font-weight: bold } /* Keyword.Constant */
23 | .highlight .kd { font-weight: bold } /* Keyword.Declaration */
24 | .highlight .kn { font-weight: bold } /* Keyword.Namespace */
25 | .highlight .kp { font-weight: bold } /* Keyword.Pseudo */
26 | .highlight .kr { font-weight: bold } /* Keyword.Reserved */
27 | .highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
28 | .highlight .m { color: #009999 } /* Literal.Number */
29 | .highlight .s { color: #d14 } /* Literal.String */
30 | .highlight .na { color: #008080 } /* Name.Attribute */
31 | .highlight .nb { color: #0086B3 } /* Name.Builtin */
32 | .highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
33 | .highlight .no { color: #008080 } /* Name.Constant */
34 | .highlight .ni { color: #800080 } /* Name.Entity */
35 | .highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
36 | .highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
37 | .highlight .nn { color: #555555 } /* Name.Namespace */
38 | .highlight .nt { color: #000080 } /* Name.Tag */
39 | .highlight .nv { color: #008080 } /* Name.Variable */
40 | .highlight .ow { font-weight: bold } /* Operator.Word */
41 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */
42 | .highlight .mf { color: #009999 } /* Literal.Number.Float */
43 | .highlight .mh { color: #009999 } /* Literal.Number.Hex */
44 | .highlight .mi { color: #009999 } /* Literal.Number.Integer */
45 | .highlight .mo { color: #009999 } /* Literal.Number.Oct */
46 | .highlight .sb { color: #d14 } /* Literal.String.Backtick */
47 | .highlight .sc { color: #d14 } /* Literal.String.Char */
48 | .highlight .sd { color: #d14 } /* Literal.String.Doc */
49 | .highlight .s2 { color: #d14 } /* Literal.String.Double */
50 | .highlight .se { color: #d14 } /* Literal.String.Escape */
51 | .highlight .sh { color: #d14 } /* Literal.String.Heredoc */
52 | .highlight .si { color: #d14 } /* Literal.String.Interpol */
53 | .highlight .sx { color: #d14 } /* Literal.String.Other */
54 | .highlight .sr { color: #009926 } /* Literal.String.Regex */
55 | .highlight .s1 { color: #d14 } /* Literal.String.Single */
56 | .highlight .ss { color: #990073 } /* Literal.String.Symbol */
57 | .highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
58 | .highlight .vc { color: #008080 } /* Name.Variable.Class */
59 | .highlight .vg { color: #008080 } /* Name.Variable.Global */
60 | .highlight .vi { color: #008080 } /* Name.Variable.Instance */
61 | .highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
62 |
63 | .type-csharp .highlight .k { color: #0000FF }
64 | .type-csharp .highlight .kt { color: #0000FF }
65 | .type-csharp .highlight .nf { color: #000000; font-weight: normal }
66 | .type-csharp .highlight .nc { color: #2B91AF }
67 | .type-csharp .highlight .nn { color: #000000 }
68 | .type-csharp .highlight .s { color: #A31515 }
69 | .type-csharp .highlight .sc { color: #A31515 }
70 |
--------------------------------------------------------------------------------
/src/config/editor/css/stylesheet.css:
--------------------------------------------------------------------------------
1 | /*! normalize.css v3.0.0 | MIT License | git.io/normalize */
2 |
3 | /**
4 | * 1. Set default font family to sans-serif.
5 | * 2. Prevent iOS text size adjust after orientation change, without disabling
6 | * user zoom.
7 | */
8 |
9 | html {
10 | font-family: sans-serif; /* 1 */
11 | -ms-text-size-adjust: 100%; /* 2 */
12 | -webkit-text-size-adjust: 100%; /* 2 */
13 | }
14 |
15 | /**
16 | * Remove default margin.
17 | */
18 |
19 | body {
20 | margin: 0;
21 | }
22 |
23 | /* HTML5 display definitions
24 | ========================================================================== */
25 |
26 | /**
27 | * Correct `block` display not defined for any HTML5 element in IE 8/9.
28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11 and Firefox.
29 | * Correct `block` display not defined for `main` in IE 11.
30 | */
31 |
32 | article,
33 | aside,
34 | details,
35 | figcaption,
36 | figure,
37 | footer,
38 | header,
39 | hgroup,
40 | main,
41 | nav,
42 | section,
43 | summary {
44 | display: block;
45 | }
46 |
47 | /**
48 | * 1. Correct `inline-block` display not defined in IE 8/9.
49 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
50 | */
51 |
52 | audio,
53 | canvas,
54 | progress,
55 | video {
56 | display: inline-block; /* 1 */
57 | vertical-align: baseline; /* 2 */
58 | }
59 |
60 | /**
61 | * Prevent modern browsers from displaying `audio` without controls.
62 | * Remove excess height in iOS 5 devices.
63 | */
64 |
65 | audio:not([controls]) {
66 | display: none;
67 | height: 0;
68 | }
69 |
70 | /**
71 | * Address `[hidden]` styling not present in IE 8/9/10.
72 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
73 | */
74 |
75 | [hidden],
76 | template {
77 | display: none;
78 | }
79 |
80 | /* Links
81 | ========================================================================== */
82 |
83 | /**
84 | * Remove the gray background color from active links in IE 10.
85 | */
86 |
87 | a {
88 | background: transparent;
89 | }
90 |
91 | /**
92 | * Improve readability when focused and also mouse hovered in all browsers.
93 | */
94 |
95 | a:active,
96 | a:hover {
97 | outline: 0;
98 | }
99 |
100 | /* Text-level semantics
101 | ========================================================================== */
102 |
103 | /**
104 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
105 | */
106 |
107 | abbr[title] {
108 | border-bottom: 1px dotted;
109 | }
110 |
111 | /**
112 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
113 | */
114 |
115 | b,
116 | strong {
117 | font-weight: bold;
118 | }
119 |
120 | /**
121 | * Address styling not present in Safari and Chrome.
122 | */
123 |
124 | dfn {
125 | font-style: italic;
126 | }
127 |
128 | /**
129 | * Address variable `h1` font-size and margin within `section` and `article`
130 | * contexts in Firefox 4+, Safari, and Chrome.
131 | */
132 |
133 | h1 {
134 | font-size: 2em;
135 | margin: 0.67em 0;
136 | }
137 |
138 | /**
139 | * Address styling not present in IE 8/9.
140 | */
141 |
142 | mark {
143 | background: #ff0;
144 | color: #000;
145 | }
146 |
147 | /**
148 | * Address inconsistent and variable font size in all browsers.
149 | */
150 |
151 | small {
152 | font-size: 80%;
153 | }
154 |
155 | /**
156 | * Prevent `sub` and `sup` affecting `line-height` in all browsers.
157 | */
158 |
159 | sub,
160 | sup {
161 | font-size: 75%;
162 | line-height: 0;
163 | position: relative;
164 | vertical-align: baseline;
165 | }
166 |
167 | sup {
168 | top: -0.5em;
169 | }
170 |
171 | sub {
172 | bottom: -0.25em;
173 | }
174 |
175 | /* Embedded content
176 | ========================================================================== */
177 |
178 | /**
179 | * Remove border when inside `a` element in IE 8/9/10.
180 | */
181 |
182 | img {
183 | border: 0;
184 | }
185 |
186 | /**
187 | * Correct overflow not hidden in IE 9/10/11.
188 | */
189 |
190 | svg:not(:root) {
191 | overflow: hidden;
192 | }
193 |
194 | /* Grouping content
195 | ========================================================================== */
196 |
197 | /**
198 | * Address margin not present in IE 8/9 and Safari.
199 | */
200 |
201 | figure {
202 | margin: 1em 40px;
203 | }
204 |
205 | /**
206 | * Address differences between Firefox and other browsers.
207 | */
208 |
209 | hr {
210 | -moz-box-sizing: content-box;
211 | box-sizing: content-box;
212 | height: 0;
213 | }
214 |
215 | /**
216 | * Contain overflow in all browsers.
217 | */
218 |
219 | pre {
220 | overflow: auto;
221 | }
222 |
223 | /**
224 | * Address odd `em`-unit font size rendering in all browsers.
225 | */
226 |
227 | code,
228 | kbd,
229 | pre,
230 | samp {
231 | font-family: monospace, monospace;
232 | font-size: 1em;
233 | }
234 |
235 | /* Forms
236 | ========================================================================== */
237 |
238 | /**
239 | * Known limitation: by default, Chrome and Safari on OS X allow very limited
240 | * styling of `select`, unless a `border` property is set.
241 | */
242 |
243 | /**
244 | * 1. Correct color not being inherited.
245 | * Known issue: affects color of disabled elements.
246 | * 2. Correct font properties not being inherited.
247 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
248 | */
249 |
250 | button,
251 | input,
252 | optgroup,
253 | select,
254 | textarea {
255 | color: inherit; /* 1 */
256 | font: inherit; /* 2 */
257 | margin: 0; /* 3 */
258 | }
259 |
260 | /**
261 | * Address `overflow` set to `hidden` in IE 8/9/10/11.
262 | */
263 |
264 | button {
265 | overflow: visible;
266 | }
267 |
268 | /**
269 | * Address inconsistent `text-transform` inheritance for `button` and `select`.
270 | * All other form control elements do not inherit `text-transform` values.
271 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
272 | * Correct `select` style inheritance in Firefox.
273 | */
274 |
275 | button,
276 | select {
277 | text-transform: none;
278 | }
279 |
280 | /**
281 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
282 | * and `video` controls.
283 | * 2. Correct inability to style clickable `input` types in iOS.
284 | * 3. Improve usability and consistency of cursor style between image-type
285 | * `input` and others.
286 | */
287 |
288 | button,
289 | html input[type="button"], /* 1 */
290 | input[type="reset"],
291 | input[type="submit"] {
292 | -webkit-appearance: button; /* 2 */
293 | cursor: pointer; /* 3 */
294 | }
295 |
296 | /**
297 | * Re-set default cursor for disabled elements.
298 | */
299 |
300 | button[disabled],
301 | html input[disabled] {
302 | cursor: default;
303 | }
304 |
305 | /**
306 | * Remove inner padding and border in Firefox 4+.
307 | */
308 |
309 | button::-moz-focus-inner,
310 | input::-moz-focus-inner {
311 | border: 0;
312 | padding: 0;
313 | }
314 |
315 | /**
316 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in
317 | * the UA stylesheet.
318 | */
319 |
320 | input {
321 | line-height: normal;
322 | }
323 |
324 | /**
325 | * It's recommended that you don't attempt to style these elements.
326 | * Firefox's implementation doesn't respect box-sizing, padding, or width.
327 | *
328 | * 1. Address box sizing set to `content-box` in IE 8/9/10.
329 | * 2. Remove excess padding in IE 8/9/10.
330 | */
331 |
332 | input[type="checkbox"],
333 | input[type="radio"] {
334 | box-sizing: border-box; /* 1 */
335 | padding: 0; /* 2 */
336 | }
337 |
338 | /**
339 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain
340 | * `font-size` values of the `input`, it causes the cursor style of the
341 | * decrement button to change from `default` to `text`.
342 | */
343 |
344 | input[type="number"]::-webkit-inner-spin-button,
345 | input[type="number"]::-webkit-outer-spin-button {
346 | height: auto;
347 | }
348 |
349 | /**
350 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
351 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
352 | * (include `-moz` to future-proof).
353 | */
354 |
355 | input[type="search"] {
356 | -webkit-appearance: textfield; /* 1 */
357 | -moz-box-sizing: content-box;
358 | -webkit-box-sizing: content-box; /* 2 */
359 | box-sizing: content-box;
360 | }
361 |
362 | /**
363 | * Remove inner padding and search cancel button in Safari and Chrome on OS X.
364 | * Safari (but not Chrome) clips the cancel button when the search input has
365 | * padding (and `textfield` appearance).
366 | */
367 |
368 | input[type="search"]::-webkit-search-cancel-button,
369 | input[type="search"]::-webkit-search-decoration {
370 | -webkit-appearance: none;
371 | }
372 |
373 | /**
374 | * Define consistent border, margin, and padding.
375 | */
376 |
377 | fieldset {
378 | border: 1px solid #c0c0c0;
379 | margin: 0 2px;
380 | padding: 0.35em 0.625em 0.75em;
381 | }
382 |
383 | /**
384 | * 1. Correct `color` not being inherited in IE 8/9/10/11.
385 | * 2. Remove padding so people aren't caught out if they zero out fieldsets.
386 | */
387 |
388 | legend {
389 | border: 0; /* 1 */
390 | padding: 0; /* 2 */
391 | }
392 |
393 | /**
394 | * Remove default vertical scrollbar in IE 8/9/10/11.
395 | */
396 |
397 | textarea {
398 | overflow: auto;
399 | }
400 |
401 | /**
402 | * Don't inherit the `font-weight` (applied by a rule above).
403 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
404 | */
405 |
406 | optgroup {
407 | font-weight: bold;
408 | }
409 |
410 | /* Tables
411 | ========================================================================== */
412 |
413 | /**
414 | * Remove most spacing between table cells.
415 | */
416 |
417 | table {
418 | border-collapse: collapse;
419 | border-spacing: 0;
420 | }
421 |
422 | td,
423 | th {
424 | padding: 0;
425 | }
426 |
427 |
428 | /* Style */
429 |
430 | body {
431 | font-size: 15px;
432 | font-family: Arial, Arial, Helvetica, sans-serif;
433 | line-height: 1.5;
434 | background: #D1D1D1;
435 | }
436 |
437 | a {
438 | color: #63a52a;
439 | text-decoration: none;
440 | transition: opacity ease-in-out 0.3s;
441 | -webkit-transition: opacity ease-in-out 0.3s; /* Safari <=6.1, Android <= 4.3 */
442 | }
443 |
444 | a:hover {
445 | text-decoration: underline;
446 | color: #90D355;
447 | }
448 |
449 | h1.title {
450 | margin: 30px 20px 10px;
451 | font-size: 60px;
452 | font-weight: bold;
453 | font-style: italic;
454 | font-family:Georgia, serif;
455 | text-align: center;
456 | }
457 |
458 | .wrapper {
459 | width: 675px;
460 | margin: 0 auto;
461 | }
462 |
463 | #container {
464 | border: 1px solid #2a2a2a;
465 | background: #ddd url(../images/pattern.png);
466 | box-shadow: 0 0 5px #b1b1b1;
467 | }
468 |
469 | p.tagline {
470 | padding: 20px 20px 0;
471 | color: #fff;
472 | font-size: 17px;
473 | }
474 |
475 | #main {
476 | margin-top: 20px;
477 | padding: 0 20px 90px;
478 | background-color: #fff;
479 | }
480 |
481 | .download-bar {
482 | background: #222;
483 | border: 5px solid #444;
484 | padding: 10px;
485 | margin: 0 -35px 20px;
486 | position: relative;
487 | }
488 |
489 | .download-bar .inner {
490 | overflow: hidden;
491 | }
492 |
493 | .download-bar .watch-fork iframe {
494 | display: block;
495 | float: left;
496 | border-right: 1px solid #ddd;
497 | padding-right: 5px;
498 | }
499 | .download-bar .watch-fork iframe.last {
500 | border-right: 0 none;
501 | padding-right: 0;
502 | padding-left: 5px;
503 | border-left: 1px solid #fff;
504 | }
505 | .download-bar .watch-fork {
506 | overflow: hidden;
507 | float: right;
508 | background-color: #eee;
509 | padding: 5px;
510 | border-radius: 3px;
511 | }
512 |
513 | .download-bar .blc {
514 | border: 10px solid black;
515 | border-color: transparent transparent black;
516 | width: 0;
517 | height: 0;
518 | display: block;
519 | position: absolute;
520 | bottom: -15px;
521 | left: 0;
522 | transform: rotate(45deg);
523 | -ms-transform: rotate(45deg); /* IE9 */
524 | -webkit-transform: rotate(45deg); /* 2014 current */
525 | }
526 |
527 | .download-bar .trc {
528 | border: 10px solid black;
529 | border-color: black transparent transparent;
530 | width: 0;
531 | height: 0;
532 | display: block;
533 | position: absolute;
534 | top: -15px;
535 | right: 0;
536 | transform: rotate(45deg);
537 | -ms-transform: rotate(45deg); /* IE9 */
538 | -webkit-transform: rotate(45deg); /* 2014 current */
539 | }
540 |
541 | .download-bar .avatar {
542 | border: 1px solid black;
543 | display: block;
544 | padding: 4px;
545 | float: left;
546 | }
547 |
548 | .download-bar .avatar img {
549 | display: block;
550 | }
551 |
552 | .download-bar a.code {
553 | background: transparent url(../images/code.png) no-repeat 0 2px;
554 | padding-left: 35px;
555 | margin-top: 8px;
556 | display: block;
557 | float: left;
558 | text-indent: 0;
559 | width: auto;
560 | height: auto;
561 | opacity: 1;
562 | filter:alpha(opacity=100); /* IE 5-7 */
563 | }
564 |
565 | .current-section {
566 | position: fixed;
567 | top: 0;
568 | left: 50%;
569 | width: 693px;
570 | margin-left: -352px;
571 | background: #222;
572 | border: 5px solid #444;
573 | color: #fff;
574 | opacity: 0;
575 | visibility: hidden;
576 | transition: opacity ease-in-out 0.3s;
577 | -webkit-transition: opacity ease-in-out 0.3s; /* Safari <=6.1, Android <= 4.3 */
578 | }
579 |
580 | .current-section p {
581 | padding: 5px 27px;
582 | font-size: 24px;
583 | font-weight: bold;
584 | }
585 |
586 | .current-section a {
587 | float: right;
588 | text-indent: -10000px;
589 | background: transparent url(../images/top.png) no-repeat 0 0;
590 | width: 20px;
591 | height: 20px;
592 | opacity: 0.8;
593 | margin-right: 12px;
594 | margin-top: 12px;
595 | opacity: 0.8;
596 | filter:alpha(opacity=80); /* IE 5-7 */
597 | transition: opacity ease-in-out 0.3s;
598 | -webkit-transition: opacity ease-in-out 0.3s; /* Safari <=6.1, Android <= 4.3 */
599 | }
600 |
601 | .current-section a:hover {
602 | opacity: 1;
603 | filter:alpha(opacity=100); /* IE 5-7 */
604 | }
605 |
606 | .current-section a.zip {
607 | margin-right: 8px;
608 | }
609 |
610 | a.zip,
611 | a.zip span {
612 | background: transparent url(../images/zip.png) no-repeat 0 0;
613 | width: 30px;
614 | height: 21px;
615 | display: inline-block;
616 | text-indent: -10000px;
617 | opacity: 0.8;
618 | filter:alpha(opacity=80); /* IE 5-7 */
619 | transition: opacity ease-in-out 0.3s;
620 | -webkit-transition: opacity ease-in-out 0.3s; /* Safari <=6.1, Android <= 4.3 */
621 | }
622 |
623 | a.tar,
624 | a.tar span {
625 | background: transparent url(../images/tar.png) no-repeat 0 0;
626 | width: 30px;
627 | height: 21px;
628 | display: inline-block;
629 | text-indent: -10000px;
630 | opacity: 0.8;
631 | filter:alpha(opacity=80); /* IE 5-7 */
632 | transition: opacity ease-in-out 0.3s;
633 | -webkit-transition: opacity ease-in-out 0.3s; /* Safari <=6.1, Android <= 4.3 */
634 | }
635 |
636 | a.code {
637 | background: transparent url(../images/code.png) no-repeat 0 2px;
638 | width: 30px;
639 | height: 21px;
640 | display: block;
641 | display: inline-block;
642 | text-indent: -10000px;
643 | opacity: 0.8;
644 | filter:alpha(opacity=80); /* IE 5-7 */
645 | transition: opacity ease-in-out 0.3s;
646 | -webkit-transition: opacity ease-in-out 0.3s; /* Safari <=6.1, Android <= 4.3 */
647 | }
648 |
649 | a.zip:hover,
650 | a.tar:hover,
651 | a.code:hover {
652 | opacity: 1;
653 | filter:alpha(opacity=100);
654 | }
655 |
656 | a.download-button {
657 | border: 1px solid black;
658 | border-radius: 3px;
659 | display: inline-block;
660 | text-indent: 0!important;
661 | width: auto;
662 | float: right;
663 | background: #999; /* for non-css3 browsers */
664 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#37ADD4', endColorstr='#1B657E'); /* IE <= 9 */
665 | background: -webkit-gradient(linear, left top, left bottom, from(#37ADD4), to(#1B657E)); /* ancient webkit browsers */
666 | background: -webkit-linear-gradient(top, #37ADD4, #1B657E); /* Safari <=6.1, Android <= 4.3 */
667 | background: linear-gradient(to bottom, #37ADD4, #1B657E);
668 | height: auto;
669 | margin-left: 10px;
670 | }
671 |
672 | a.download-button span {
673 | background-position: 10px 5px;
674 | width: auto;
675 | height: auto;
676 | padding: 5px 10px;
677 | padding-left: 45px;
678 | display: inline-block;
679 | text-indent: 0!important;
680 | color: #fff;
681 | }
682 |
683 | footer {
684 | margin-bottom: 60px;
685 | padding-bottom: 60px;
686 | }
687 |
688 | footer .owner {
689 | background: #222;
690 | border: 5px solid #444;
691 | padding: 5px 15px;
692 | margin: -67px -10px 35px;
693 | color: #d6d6d6;
694 | }
695 |
696 | footer .creds small {
697 | float: right;
698 | font-size: 10px;
699 | text-align: right;
700 | margin-left: 15px;
701 | }
702 |
703 | footer .owner .avatar {
704 | background-color: #666;
705 | display: block;
706 | margin: -19px 10px 0 0;
707 | width: 60px;
708 | float: left;
709 | }
710 |
711 | footer .owner img {
712 | display: block;
713 | border: 1px solid #2a2a2a;
714 | margin: 5px;
715 | }
716 |
717 | footer .owner p {
718 | font-family:Georgia, serif;
719 | }
720 |
721 | footer .owner p a {
722 | font-size: 16px;
723 | font-style: italic;
724 | }
725 |
726 | /* Markdown */
727 | .markdown-body h1,
728 | .markdown-body h2,
729 | .markdown-body h3,
730 | .markdown-body h4,
731 | .markdown-body h5,
732 | .markdown-body h6,
733 | .markdown-body p,
734 | .markdown-body pre,
735 | .markdown-body ul,
736 | .markdown-body ol,
737 | .markdown-body dl,
738 | .markdown-body table,
739 | .markdown-body blockquote {
740 | margin-bottom: 20px;
741 | }
742 |
743 | .markdown-body h1,
744 | .markdown-body h2,
745 | .markdown-body h3,
746 | .markdown-body h4,
747 | .markdown-body h5,
748 | .markdown-body h6 {
749 | font-weight: bold;
750 | }
751 |
752 | .markdown-body h1 {
753 | font-size: 28px;
754 | }
755 |
756 | .markdown-body h2 {
757 | font-size: 24px;
758 | color: #557398;
759 | }
760 |
761 | .markdown-body h3 {
762 | font-size: 20px;
763 | }
764 |
765 | .markdown-body h4 {
766 | font-size: 18px;
767 | }
768 |
769 | .markdown-body h5 {
770 | font-size: 16px;
771 | }
772 |
773 | .markdown-body pre {
774 | padding: 10px 70px 10px 0;
775 | margin-left: -20px;
776 | margin-right: -20px;
777 | font-family: 'Monaco', 'Lucida Console', monospace;
778 | font-size: 13px;
779 | line-height: 20px;
780 | box-shadow: inset 0 0 5px #000;
781 | word-wrap: break-word;
782 | background-color:#3b3b3b;
783 | color: #d6d6d6;
784 | }
785 |
786 | .markdown-body pre.lines {
787 | font-size: 12px;
788 | margin:0 10px 0 -20px;
789 | padding: 10px;
790 | float: left;
791 | display: block;
792 | text-align: right;
793 | box-shadow: none;
794 | background-color:#2a2a2a;
795 | color: #d6d6d6;
796 | }
797 |
798 | .markdown-body ul,
799 | .markdown-body ol {
800 | padding-left: 30px;
801 | }
802 |
803 | .markdown-body ul {
804 | list-style-type: disc;
805 | }
806 |
807 | .markdown-body ol {
808 | list-style-type: decimal;
809 | }
810 |
811 | .markdown-body li,
812 | .markdown-body li p,
813 | .markdown-body dd,
814 | .markdown-body dd p {
815 | margin-bottom: 10px;
816 | }
817 |
818 | .markdown-body li pre,
819 | .markdown-body li pre.lines,
820 | .markdown-body dd pre,
821 | .markdown-body dd pre.lines {
822 | margin-left: -35px;
823 | }
824 |
825 | .markdown-body dt {
826 | font-weight: bold;
827 | font-style: italic;
828 | }
829 |
830 | .markdown-body dd {
831 | margin-left: 15px;
832 | }
833 |
834 | .markdown-body table {
835 | width: 673px;
836 | margin-left: -20px;
837 | margin-right: -20px;
838 | }
839 |
840 | .markdown-body tbody {
841 | border-top: 2px solid #557398;
842 | border-bottom: 2px solid #557398;
843 | background-color: #EBEFF4;
844 | }
845 |
846 | .markdown-body table td * {
847 | margin: 0;
848 | }
849 |
850 | .markdown-body td {
851 | border-right: 1px solid #557398;
852 | border-bottom: 1px solid #557398;
853 | padding: 5px;
854 | }
855 |
856 | .markdown-body td:first-child,
857 | .markdown-body th:first-child {
858 | width: 30%;
859 | padding-left: 20px;
860 | }
861 |
862 | .markdown-body td:last-child {
863 | border-right: 0 none;
864 | }
865 |
866 | .markdown-body th {
867 | font-size: 18px;
868 | font-weight: bold;
869 | text-align: left;
870 | padding: 5px;
871 | }
872 |
873 | .markdown-body tt {
874 | background-color:#3b3b3b;
875 | color: #d6d6d6;
876 | padding: 2px 3px;
877 | }
878 |
879 | .markdown-body blockquote {
880 | font-style: italic;
881 | font-family:Georgia, serif;
882 | font-size: 17px;
883 | border-top: 3px solid #333;
884 | border-bottom: 3px solid #333;
885 | padding: 10px 20px;
886 | padding-left: 50px;
887 | }
888 |
889 | .markdown-body blockquote:before {
890 | font-style: italic;
891 | font-family: Georgia, serif;
892 | font-size: 90px;
893 | height: 90px;
894 | margin-left: -60px;
895 | margin-top: -25px;
896 | content: "‟";
897 | display: block;
898 | float: left;
899 | }
900 |
901 | .markdown-body img {
902 | max-width: 100%;
903 | box-sizing: border-box;
904 | }
905 |
906 | .highlight { background: #ffffff; }
907 | .highlight .c { color: #999988; font-style: italic } /* Comment */
908 | .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
909 | .highlight .k { font-weight: bold } /* Keyword */
910 | .highlight .o { font-weight: bold } /* Operator */
911 | .highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
912 | .highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
913 | .highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
914 | .highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
915 | .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
916 | .highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
917 | .highlight .ge { font-style: italic } /* Generic.Emph */
918 | .highlight .gr { color: #aa0000 } /* Generic.Error */
919 | .highlight .gh { color: #999999 } /* Generic.Heading */
920 | .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
921 | .highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
922 | .highlight .go { color: #888888 } /* Generic.Output */
923 | .highlight .gp { color: #555555 } /* Generic.Prompt */
924 | .highlight .gs { font-weight: bold } /* Generic.Strong */
925 | .highlight .gu { color: #800080; font-weight: bold; } /* Generic.Subheading */
926 | .highlight .gt { color: #aa0000 } /* Generic.Traceback */
927 | .highlight .kc { font-weight: bold } /* Keyword.Constant */
928 | .highlight .kd { font-weight: bold } /* Keyword.Declaration */
929 | .highlight .kn { font-weight: bold } /* Keyword.Namespace */
930 | .highlight .kp { font-weight: bold } /* Keyword.Pseudo */
931 | .highlight .kr { font-weight: bold } /* Keyword.Reserved */
932 | .highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
933 | .highlight .m { color: #009999 } /* Literal.Number */
934 | .highlight .s { color: #d14 } /* Literal.String */
935 | .highlight .na { color: #008080 } /* Name.Attribute */
936 | .highlight .nb { color: #0086B3 } /* Name.Builtin */
937 | .highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
938 | .highlight .no { color: #008080 } /* Name.Constant */
939 | .highlight .ni { color: #800080 } /* Name.Entity */
940 | .highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
941 | .highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
942 | .highlight .nn { color: #555555 } /* Name.Namespace */
943 | .highlight .nt { color: #000080 } /* Name.Tag */
944 | .highlight .nv { color: #008080 } /* Name.Variable */
945 | .highlight .ow { font-weight: bold } /* Operator.Word */
946 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */
947 | .highlight .mf { color: #009999 } /* Literal.Number.Float */
948 | .highlight .mh { color: #009999 } /* Literal.Number.Hex */
949 | .highlight .mi { color: #009999 } /* Literal.Number.Integer */
950 | .highlight .mo { color: #009999 } /* Literal.Number.Oct */
951 | .highlight .sb { color: #d14 } /* Literal.String.Backtick */
952 | .highlight .sc { color: #d14 } /* Literal.String.Char */
953 | .highlight .sd { color: #d14 } /* Literal.String.Doc */
954 | .highlight .s2 { color: #d14 } /* Literal.String.Double */
955 | .highlight .se { color: #d14 } /* Literal.String.Escape */
956 | .highlight .sh { color: #d14 } /* Literal.String.Heredoc */
957 | .highlight .si { color: #d14 } /* Literal.String.Interpol */
958 | .highlight .sx { color: #d14 } /* Literal.String.Other */
959 | .highlight .sr { color: #009926 } /* Literal.String.Regex */
960 | .highlight .s1 { color: #d14 } /* Literal.String.Single */
961 | .highlight .ss { color: #990073 } /* Literal.String.Symbol */
962 | .highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
963 | .highlight .vc { color: #008080 } /* Name.Variable.Class */
964 | .highlight .vg { color: #008080 } /* Name.Variable.Global */
965 | .highlight .vi { color: #008080 } /* Name.Variable.Instance */
966 | .highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
--------------------------------------------------------------------------------
/src/config/editor/css/zoom.css:
--------------------------------------------------------------------------------
1 | img[data-action="zoom"] {
2 | cursor: pointer;
3 | cursor: -webkit-zoom-in;
4 | cursor: -moz-zoom-in;
5 | }
6 | .zoom-img,
7 | .zoom-img-wrap {
8 | position: relative;
9 | z-index: 666;
10 | -webkit-transition: all 300ms;
11 | -o-transition: all 300ms;
12 | transition: all 300ms;
13 | }
14 | img.zoom-img {
15 | cursor: pointer;
16 | cursor: -webkit-zoom-out;
17 | cursor: -moz-zoom-out;
18 | }
19 | .zoom-overlay {
20 | z-index: 420;
21 | background: #fff;
22 | position: fixed;
23 | top: 0;
24 | left: 0;
25 | right: 0;
26 | bottom: 0;
27 | pointer-events: none;
28 | filter: "alpha(opacity=0)";
29 | opacity: 0;
30 | -webkit-transition: opacity 300ms;
31 | -o-transition: opacity 300ms;
32 | transition: opacity 300ms;
33 | }
34 | .zoom-overlay-open .zoom-overlay {
35 | filter: "alpha(opacity=100)";
36 | opacity: 1;
37 | }
38 | .zoom-overlay-open,
39 | .zoom-overlay-transitioning {
40 | cursor: default;
41 | }
42 |
--------------------------------------------------------------------------------
/src/config/editor/images/code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endachao/laravel-5-markdown-editor/420f93671d19b6edff7bd045ed728704c4e083c2/src/config/editor/images/code.png
--------------------------------------------------------------------------------
/src/config/editor/images/editor@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endachao/laravel-5-markdown-editor/420f93671d19b6edff7bd045ed728704c4e083c2/src/config/editor/images/editor@2x.png
--------------------------------------------------------------------------------
/src/config/editor/images/loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endachao/laravel-5-markdown-editor/420f93671d19b6edff7bd045ed728704c4e083c2/src/config/editor/images/loader.gif
--------------------------------------------------------------------------------
/src/config/editor/images/pattern.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endachao/laravel-5-markdown-editor/420f93671d19b6edff7bd045ed728704c4e083c2/src/config/editor/images/pattern.png
--------------------------------------------------------------------------------
/src/config/editor/images/tar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endachao/laravel-5-markdown-editor/420f93671d19b6edff7bd045ed728704c4e083c2/src/config/editor/images/tar.png
--------------------------------------------------------------------------------
/src/config/editor/images/top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endachao/laravel-5-markdown-editor/420f93671d19b6edff7bd045ed728704c4e083c2/src/config/editor/images/top.png
--------------------------------------------------------------------------------
/src/config/editor/images/zip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/endachao/laravel-5-markdown-editor/420f93671d19b6edff7bd045ed728704c4e083c2/src/config/editor/images/zip.png
--------------------------------------------------------------------------------
/src/config/editor/js/MIDI.js:
--------------------------------------------------------------------------------
1 | if(typeof MIDI==="undefined")var MIDI={};(function(){"use strict";var e={};var t=0;var n=function(n){t++;var r=new Audio;var i=n.split(";")[0];r.id="audio";r.setAttribute("preload","auto");r.setAttribute("audiobuffer",true);r.addEventListener("error",function(){e[i]=false;t--},false);r.addEventListener("canplaythrough",function(){e[i]=true;t--},false);r.src="data:"+n;document.body.appendChild(r)};MIDI.audioDetect=function(r){if(typeof Audio==="undefined")return r({});var i=new Audio;if(typeof i.canPlayType==="undefined")return r(e);var s=i.canPlayType('audio/ogg; codecs="vorbis"');s=s==="probably"||s==="maybe";var o=i.canPlayType("audio/mpeg");o=o==="probably"||o==="maybe";if(!s&&!o){r(e);return}if(s)n("audio/ogg;base64,T2dnUwACAAAAAAAAAADqnjMlAAAAAOyyzPIBHgF2b3JiaXMAAAAAAUAfAABAHwAAQB8AAEAfAACZAU9nZ1MAAAAAAAAAAAAA6p4zJQEAAAANJGeqCj3//////////5ADdm9yYmlzLQAAAFhpcGguT3JnIGxpYlZvcmJpcyBJIDIwMTAxMTAxIChTY2hhdWZlbnVnZ2V0KQAAAAABBXZvcmJpcw9CQ1YBAAABAAxSFCElGVNKYwiVUlIpBR1jUFtHHWPUOUYhZBBTiEkZpXtPKpVYSsgRUlgpRR1TTFNJlVKWKUUdYxRTSCFT1jFloXMUS4ZJCSVsTa50FkvomWOWMUYdY85aSp1j1jFFHWNSUkmhcxg6ZiVkFDpGxehifDA6laJCKL7H3lLpLYWKW4q91xpT6y2EGEtpwQhhc+211dxKasUYY4wxxsXiUyiC0JBVAAABAABABAFCQ1YBAAoAAMJQDEVRgNCQVQBABgCAABRFcRTHcRxHkiTLAkJDVgEAQAAAAgAAKI7hKJIjSZJkWZZlWZameZaouaov+64u667t6roOhIasBACAAAAYRqF1TCqDEEPKQ4QUY9AzoxBDDEzGHGNONKQMMogzxZAyiFssLqgQBKEhKwKAKAAAwBjEGGIMOeekZFIi55iUTkoDnaPUUcoolRRLjBmlEluJMYLOUeooZZRCjKXFjFKJscRUAABAgAMAQICFUGjIigAgCgCAMAYphZRCjCnmFHOIMeUcgwwxxiBkzinoGJNOSuWck85JiRhjzjEHlXNOSuekctBJyaQTAAAQ4AAAEGAhFBqyIgCIEwAwSJKmWZomipamiaJniqrqiaKqWp5nmp5pqqpnmqpqqqrrmqrqypbnmaZnmqrqmaaqiqbquqaquq6nqrZsuqoum65q267s+rZru77uqapsm6or66bqyrrqyrbuurbtS56nqqKquq5nqq6ruq5uq65r25pqyq6purJtuq4tu7Js664s67pmqq5suqotm64s667s2rYqy7ovuq5uq7Ks+6os+75s67ru2rrwi65r66os674qy74x27bwy7ouHJMnqqqnqq7rmarrqq5r26rr2rqmmq5suq4tm6or26os67Yry7aumaosm64r26bryrIqy77vyrJui67r66Ys67oqy8Lu6roxzLat+6Lr6roqy7qvyrKuu7ru+7JuC7umqrpuyrKvm7Ks+7auC8us27oxuq7vq7It/KosC7+u+8Iy6z5jdF1fV21ZGFbZ9n3d95Vj1nVhWW1b+V1bZ7y+bgy7bvzKrQvLstq2scy6rSyvrxvDLux8W/iVmqratum6um7Ksq/Lui60dd1XRtf1fdW2fV+VZd+3hV9pG8OwjK6r+6os68Jry8ov67qw7MIvLKttK7+r68ow27qw3L6wLL/uC8uq277v6rrStXVluX2fsSu38QsAABhwAAAIMKEMFBqyIgCIEwBAEHIOKQahYgpCCKGkEEIqFWNSMuakZM5JKaWUFEpJrWJMSuaclMwxKaGUlkopqYRSWiqlxBRKaS2l1mJKqcVQSmulpNZKSa2llGJMrcUYMSYlc05K5pyUklJrJZXWMucoZQ5K6iCklEoqraTUYuacpA46Kx2E1EoqMZWUYgupxFZKaq2kFGMrMdXUWo4hpRhLSrGVlFptMdXWWqs1YkxK5pyUzDkqJaXWSiqtZc5J6iC01DkoqaTUYiopxco5SR2ElDLIqJSUWiupxBJSia20FGMpqcXUYq4pxRZDSS2WlFosqcTWYoy1tVRTJ6XFklKMJZUYW6y5ttZqDKXEVkqLsaSUW2sx1xZjjqGkFksrsZWUWmy15dhayzW1VGNKrdYWY40x5ZRrrT2n1mJNMdXaWqy51ZZbzLXnTkprpZQWS0oxttZijTHmHEppraQUWykpxtZara3FXEMpsZXSWiypxNhirLXFVmNqrcYWW62ltVprrb3GVlsurdXcYqw9tZRrrLXmWFNtBQAADDgAAASYUAYKDVkJAEQBAADGMMYYhEYpx5yT0ijlnHNSKucghJBS5hyEEFLKnINQSkuZcxBKSSmUklJqrYVSUmqttQIAAAocAAACbNCUWByg0JCVAEAqAIDBcTRNFFXVdX1fsSxRVFXXlW3jVyxNFFVVdm1b+DVRVFXXtW3bFn5NFFVVdmXZtoWiqrqybduybgvDqKqua9uybeuorqvbuq3bui9UXVmWbVu3dR3XtnXd9nVd+Bmzbeu2buu+8CMMR9/4IeTj+3RCCAAAT3AAACqwYXWEk6KxwEJDVgIAGQAAgDFKGYUYM0gxphhjTDHGmAAAgAEHAIAAE8pAoSErAoAoAADAOeecc84555xzzjnnnHPOOeecc44xxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY0wAwE6EA8BOhIVQaMhKACAcAABACCEpKaWUUkoRU85BSSmllFKqFIOMSkoppZRSpBR1lFJKKaWUIqWgpJJSSimllElJKaWUUkoppYw6SimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaVUSimllFJKKaWUUkoppRQAYPLgAACVYOMMK0lnhaPBhYasBAByAwAAhRiDEEJpraRUUkolVc5BKCWUlEpKKZWUUqqYgxBKKqmlklJKKbXSQSihlFBKKSWUUkooJYQQSgmhlFRCK6mEUkoHoYQSQimhhFRKKSWUzkEoIYUOQkmllNRCSB10VFIpIZVSSiklpZQ6CKGUklJLLZVSWkqpdBJSKamV1FJqqbWSUgmhpFZKSSWl0lpJJbUSSkklpZRSSymFVFJJJYSSUioltZZaSqm11lJIqZWUUkqppdRSSiWlkEpKqZSSUmollZRSaiGVlEpJKaTUSimlpFRCSamlUlpKLbWUSkmptFRSSaWUlEpJKaVSSksppRJKSqmllFpJKYWSUkoplZJSSyW1VEoKJaWUUkmptJRSSymVklIBAEAHDgAAAUZUWoidZlx5BI4oZJiAAgAAQABAgAkgMEBQMApBgDACAQAAAADAAAAfAABHARAR0ZzBAUKCwgJDg8MDAAAAAAAAAAAAAACAT2dnUwAEAAAAAAAAAADqnjMlAgAAADzQPmcBAQA=");if(o)n("audio/mpeg;base64,/+MYxAAAAANIAUAAAASEEB/jwOFM/0MM/90b/+RhST//w4NFwOjf///PZu////9lns5GFDv//l9GlUIEEIAAAgIg8Ir/JGq3/+MYxDsLIj5QMYcoAP0dv9HIjUcH//yYSg+CIbkGP//8w0bLVjUP///3Z0x5QCAv/yLjwtGKTEFNRTMuOTeqqqqqqqqqqqqq/+MYxEkNmdJkUYc4AKqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq");var u=(new Date).getTime();var a=window.setInterval(function(){var n=(new Date).getTime();var i=n-u>5e3;if(!t||i){window.clearInterval(a);r(e)}},1)}})();if(typeof MIDI==="undefined")var MIDI={};if(typeof MIDI.Soundfont==="undefined")MIDI.Soundfont={};(function(){"use strict";var e=false;MIDI.loadPlugin=function(r){if(typeof r==="function")r={callback:r};var i=r.instruments||r.instrument||"acoustic_grand_piano";if(typeof i!=="object")i=[i];for(var s=0;sProcessing: "+(n/87*100>>0)+"%
"+l)}r.id=f;i[n]=r;if(i.length===t.length){while(i.length){r=i.pop();if(!r)continue;var c=MIDI.keyToNote[r.id];o[a+""+c]=r}s(e)}})};n.setVolume=function(e,t){s=t};n.programChange=function(e,t){MIDI.channels[e].instrument=t};n.noteOn=function(e,t,n,u){if(!MIDI.channels[e])return;var a=MIDI.channels[e].instrument;if(!o[a+""+t])return;if(u>0;var s=n[r%12]+i;MIDI.keyToNote[s]=r;MIDI.noteToKey[r]=s}})()})();if(typeof MIDI==="undefined")var MIDI={};if(typeof MIDI.Player==="undefined")MIDI.Player={};(function(){"use strict";var e=MIDI.Player;e.callback=undefined;e.currentTime=0;e.endTime=0;e.restart=0;e.playing=false;e.timeWarp=1;e.start=e.resume=function(){if(e.currentTime<-1)e.currentTime=-1;f(e.currentTime)};e.pause=function(){var t=e.restart;l();e.restart=t};e.stop=function(){l();e.restart=0;e.currentTime=0};e.addListener=function(e){s=e};e.removeListener=function(){s=undefined};e.clearAnimation=function(){if(e.interval){window.clearInterval(e.interval)}};e.setAnimation=function(t){var n=typeof t==="function"?t:t.callback;var r=t.interval||30;var s=0;var o=0;var u=0;e.clearAnimation();e.interval=window.setInterval(function(){if(e.endTime===0)return;if(e.playing){s=u===e.currentTime?o-(new Date).getTime():0;if(e.currentTime===0){s=0}else{s=e.currentTime-s}if(u!==e.currentTime){o=(new Date).getTime();u=e.currentTime}}else{s=e.currentTime}var t=e.endTime;var r=s/t;var a=s/1e3;var f=a/60;var l=a-f*60;var c=f*60+l;var h=t/1e3;if(h-c<-1)return;n({now:c,end:h,events:i})},r)};e.loadMidiFile=function(){e.replayer=new Replayer(MidiFile(e.currentData),e.timeWarp);e.data=e.replayer.getData();e.endTime=a()};e.loadFile=function(t,n){e.stop();if(t.indexOf("base64,")!==-1){var r=window.atob(t.split(",")[1]);e.currentData=r;e.loadMidiFile();if(n)n(r);return}var i=new XMLHttpRequest;i.open("GET",t);i.overrideMimeType("text/plain; charset=x-user-defined");i.onreadystatechange=function(){if(this.readyState===4&&this.status===200){var t=this.responseText||"";var r=[];var i=t.length;var s=String.fromCharCode;for(var o=0;o\r\n"+"Function IEBinaryToArray_ByteStr(Binary)\r\n"+" IEBinaryToArray_ByteStr = CStr(Binary)\r\n"+"End Function\r\n"+"Function IEBinaryToArray_ByteStr_Last(Binary)\r\n"+" Dim lastIndex\r\n"+" lastIndex = LenB(Binary)\r\n"+" if lastIndex mod 2 Then\r\n"+" IEBinaryToArray_ByteStr_Last = Chr( AscB( MidB( Binary, lastIndex, 1 ) ) )\r\n"+" Else\r\n"+" IEBinaryToArray_ByteStr_Last = "+'""'+"\r\n"+" End If\r\n"+"End Function\r\n"+"\r\n";document.write(IEBinaryToArray_ByteStr_Script);DOMLoader.sendRequest=function(e){function t(e){var t={};for(var n=0;n<256;n++){for(var r=0;r<256;r++){t[String.fromCharCode(n+r*256)]=String.fromCharCode(n)+String.fromCharCode(r)}}var i=IEBinaryToArray_ByteStr(e);var s=IEBinaryToArray_ByteStr_Last(e);return i.replace(/[\s\S]/g,function(e){return t[e]})+s}var n=XMLHttpRequest();n.open("GET",e.url,true);if(e.responseType)n.responseType=e.responseType;if(e.onerror)n.onerror=e.onerror;if(e.onprogress)n.onprogress=e.onprogress;n.onreadystatechange=function(r){if(n.readyState===4){if(n.status===200){n.responseText=t(n.responseBody)}else{n=false}if(e.onload)e.onload(n)}};n.setRequestHeader("Accept-Charset","x-user-defined");n.send(null);return n}}else{DOMLoader.sendRequest=function(e){var t=new XMLHttpRequest;t.open(e.data?"POST":"GET",e.url,true);if(t.overrideMimeType)t.overrideMimeType("text/plain; charset=x-user-defined");if(e.data)t.setRequestHeader("Content-type","application/x-www-form-urlencoded");if(e.responseType)t.responseType=e.responseType;if(e.onerror)t.onerror=e.onerror;if(e.onprogress)t.onprogress=e.onprogress;t.onreadystatechange=function(n){if(t.readyState===4){if(t.status!==200&&t.status!=304){if(e.onerror)e.onerror(n,false);return}if(e.onload){e.onload(t)}}};t.send(e.data);return t}}var Base64Binary={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",decodeArrayBuffer:function(e){var t=Math.ceil(3*e.length/4);var n=new ArrayBuffer(t);this.decode(e,n);return n},decode:function(e,t){var n=this._keyStr.indexOf(e.charAt(e.length-1));var r=this._keyStr.indexOf(e.charAt(e.length-1));var i=Math.ceil(3*e.length/4);if(n==64)i--;if(r==64)i--;var s;var o,u,a;var f,l,c,h;var p=0;var d=0;if(t)s=new Uint8Array(t);else s=new Uint8Array(i);e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");for(p=0;p>4;u=(l&15)<<4|c>>2;a=(c&3)<<6|h;s[p]=o;if(c!=64)s[p+1]=u;if(h!=64)s[p+2]=a}return s}}
2 |
--------------------------------------------------------------------------------
/src/config/editor/js/bootstrap3-typeahead.js:
--------------------------------------------------------------------------------
1 | /* =============================================================
2 | * bootstrap3-typeahead.js v3.1.0
3 | * https://github.com/bassjobsen/Bootstrap-3-Typeahead
4 | * =============================================================
5 | * Original written by @mdo and @fat
6 | * =============================================================
7 | * Copyright 2014 Bass Jobsen @bassjobsen
8 | *
9 | * Licensed under the Apache License, Version 2.0 (the 'License');
10 | * you may not use this file except in compliance with the License.
11 | * You may obtain a copy of the License at
12 | *
13 | * http://www.apache.org/licenses/LICENSE-2.0
14 | *
15 | * Unless required by applicable law or agreed to in writing, software
16 | * distributed under the License is distributed on an 'AS IS' BASIS,
17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 | * See the License for the specific language governing permissions and
19 | * limitations under the License.
20 | * ============================================================ */
21 |
22 |
23 | (function (root, factory) {
24 |
25 | 'use strict';
26 |
27 | // CommonJS module is defined
28 | if (typeof module !== 'undefined' && module.exports) {
29 | module.exports = factory(require('jquery'));
30 | }
31 | // AMD module is defined
32 | else if (typeof define === 'function' && define.amd) {
33 | define(['jquery'], function ($) {
34 | return factory ($);
35 | });
36 | } else {
37 | factory(root.jQuery);
38 | }
39 |
40 | }(this, function ($) {
41 |
42 | 'use strict';
43 | // jshint laxcomma: true
44 |
45 |
46 | /* TYPEAHEAD PUBLIC CLASS DEFINITION
47 | * ================================= */
48 |
49 | var Typeahead = function (element, options) {
50 | this.$element = $(element);
51 | this.options = $.extend({}, $.fn.typeahead.defaults, options);
52 | this.matcher = this.options.matcher || this.matcher;
53 | this.sorter = this.options.sorter || this.sorter;
54 | this.select = this.options.select || this.select;
55 | this.autoSelect = typeof this.options.autoSelect == 'boolean' ? this.options.autoSelect : true;
56 | this.highlighter = this.options.highlighter || this.highlighter;
57 | this.render = this.options.render || this.render;
58 | this.updater = this.options.updater || this.updater;
59 | this.displayText = this.options.displayText || this.displayText;
60 | this.source = this.options.source;
61 | this.delay = this.options.delay;
62 | this.$menu = $(this.options.menu);
63 | this.$appendTo = this.options.appendTo ? $(this.options.appendTo) : null;
64 | this.shown = false;
65 | this.listen();
66 | this.showHintOnFocus = typeof this.options.showHintOnFocus == 'boolean' ? this.options.showHintOnFocus : false;
67 | this.afterSelect = this.options.afterSelect;
68 | this.addItem = false;
69 | };
70 |
71 | Typeahead.prototype = {
72 |
73 | constructor: Typeahead,
74 |
75 | select: function () {
76 | var val = this.$menu.find('.active').data('value');
77 | this.$element.data('active', val);
78 | if(this.autoSelect || val) {
79 | var newVal = this.updater(val);
80 | // Updater can be set to any random functions via "options" parameter in constructor above.
81 | // Add null check for cases when updater returns void or undefined.
82 | if (!newVal) {
83 | newVal = "";
84 | }
85 | this.$element
86 | .val(this.displayText(newVal) || newVal)
87 | .change();
88 | this.afterSelect(newVal);
89 | }
90 | return this.hide();
91 | },
92 |
93 | updater: function (item) {
94 | return item;
95 | },
96 |
97 | setSource: function (source) {
98 | this.source = source;
99 | },
100 |
101 | show: function () {
102 | var pos = $.extend({}, this.$element.position(), {
103 | height: this.$element[0].offsetHeight
104 | }), scrollHeight;
105 |
106 | scrollHeight = typeof this.options.scrollHeight == 'function' ?
107 | this.options.scrollHeight.call() :
108 | this.options.scrollHeight;
109 |
110 | var element;
111 | if (this.shown) {
112 | element = this.$menu;
113 | } else if (this.$appendTo) {
114 | element = this.$menu.appendTo(this.$appendTo);
115 | } else {
116 | element = this.$menu.insertAfter(this.$element);
117 | }
118 | element.css({
119 | top: pos.top + pos.height + scrollHeight
120 | , left: pos.left
121 | })
122 | .show();
123 |
124 | this.shown = true;
125 | return this;
126 | },
127 |
128 | hide: function () {
129 | this.$menu.hide();
130 | this.shown = false;
131 | return this;
132 | },
133 |
134 | lookup: function (query) {
135 | var items;
136 | if (typeof(query) != 'undefined' && query !== null) {
137 | this.query = query;
138 | } else {
139 | this.query = this.$element.val() || '';
140 | }
141 |
142 | if (this.query.length < this.options.minLength && !this.options.showHintOnFocus) {
143 | return this.shown ? this.hide() : this;
144 | }
145 |
146 | var worker = $.proxy(function() {
147 |
148 | if($.isFunction(this.source)) this.source(this.query, $.proxy(this.process, this));
149 | else if (this.source) {
150 | this.process(this.source);
151 | }
152 | }, this);
153 |
154 | clearTimeout(this.lookupWorker);
155 | this.lookupWorker = setTimeout(worker, this.delay);
156 | },
157 |
158 | process: function (items) {
159 | var that = this;
160 |
161 | items = $.grep(items, function (item) {
162 | return that.matcher(item);
163 | });
164 |
165 | items = this.sorter(items);
166 |
167 | if (!items.length && !this.options.addItem) {
168 | return this.shown ? this.hide() : this;
169 | }
170 |
171 | if (items.length > 0) {
172 | this.$element.data('active', items[0]);
173 | } else {
174 | this.$element.data('active', null);
175 | }
176 |
177 | // Add item
178 | if (this.options.addItem){
179 | items.push(this.options.addItem);
180 | }
181 |
182 | if (this.options.items == 'all') {
183 | return this.render(items).show();
184 | } else {
185 | return this.render(items.slice(0, this.options.items)).show();
186 | }
187 | },
188 |
189 | matcher: function (item) {
190 | var it = this.displayText(item);
191 | return ~it.toLowerCase().indexOf(this.query.toLowerCase());
192 | },
193 |
194 | sorter: function (items) {
195 | var beginswith = []
196 | , caseSensitive = []
197 | , caseInsensitive = []
198 | , item;
199 |
200 | while ((item = items.shift())) {
201 | var it = this.displayText(item);
202 | if (!it.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item);
203 | else if (~it.indexOf(this.query)) caseSensitive.push(item);
204 | else caseInsensitive.push(item);
205 | }
206 |
207 | return beginswith.concat(caseSensitive, caseInsensitive);
208 | },
209 |
210 | highlighter: function (item) {
211 | var html = $('');
212 | var query = this.query;
213 | var i = item.toLowerCase().indexOf(query.toLowerCase());
214 | var len, leftPart, middlePart, rightPart, strong;
215 | len = query.length;
216 | if(len === 0){
217 | return html.text(item).html();
218 | }
219 | while (i > -1) {
220 | leftPart = item.substr(0, i);
221 | middlePart = item.substr(i, len);
222 | rightPart = item.substr(i + len);
223 | strong = $('').text(middlePart);
224 | html
225 | .append(document.createTextNode(leftPart))
226 | .append(strong);
227 | item = rightPart;
228 | i = item.toLowerCase().indexOf(query.toLowerCase());
229 | }
230 | return html.append(document.createTextNode(item)).html();
231 | },
232 |
233 | render: function (items) {
234 | var that = this;
235 | var self = this;
236 | var activeFound = false;
237 | var data = [];
238 | var _category = that.options.separator;
239 |
240 | $.each(items, function (key,value) {
241 | // inject separator
242 | if (key > 0 && value[_category] !== items[key - 1][_category]){
243 | data.push({
244 | __type: 'divider'
245 | });
246 | }
247 |
248 | // inject category header
249 | if (value[_category] && (key === 0 || value[_category] !== items[key - 1][_category])){
250 | data.push({
251 | __type: 'category',
252 | name: value[_category]
253 | });
254 | }
255 | data.push(value);
256 | });
257 |
258 | items = $(data).map(function (i, item) {
259 |
260 | if ((item.__type || false) == 'category'){
261 | return $(that.options.headerHtml).text(item.name)[0];
262 | }
263 |
264 | if ((item.__type || false) == 'divider'){
265 | return $(that.options.headerDivider)[0];
266 | }
267 |
268 | var text = self.displayText(item);
269 | i = $(that.options.item).data('value', item);
270 | i.find('a').html(that.highlighter(text, item));
271 | if (text == self.$element.val()) {
272 | i.addClass('active');
273 | self.$element.data('active', item);
274 | activeFound = true;
275 | }
276 | return i[0];
277 | });
278 |
279 | if (this.autoSelect && !activeFound) {
280 | items.filter(':not(.dropdown-header)').first().addClass('active');
281 | this.$element.data('active', items.first().data('value'));
282 | }
283 | this.$menu.html(items);
284 | return this;
285 | },
286 |
287 | displayText: function(item) {
288 | return typeof item !== 'undefined' && typeof item.name != 'undefined' && item.name || item;
289 | },
290 |
291 | next: function (event) {
292 | var active = this.$menu.find('.active').removeClass('active')
293 | , next = active.next();
294 |
295 | if (!next.length) {
296 | next = $(this.$menu.find('li')[0]);
297 | }
298 |
299 | next.addClass('active');
300 | },
301 |
302 | prev: function (event) {
303 | var active = this.$menu.find('.active').removeClass('active')
304 | , prev = active.prev();
305 |
306 | if (!prev.length) {
307 | prev = this.$menu.find('li').last();
308 | }
309 |
310 | prev.addClass('active');
311 | },
312 |
313 | listen: function () {
314 | this.$element
315 | .on('focus', $.proxy(this.focus, this))
316 | .on('blur', $.proxy(this.blur, this))
317 | .on('keypress', $.proxy(this.keypress, this))
318 | .on('input', $.proxy(this.input, this))
319 | .on('keyup', $.proxy(this.keyup, this));
320 |
321 | if (this.eventSupported('keydown')) {
322 | this.$element.on('keydown', $.proxy(this.keydown, this));
323 | }
324 |
325 | this.$menu
326 | .on('click', $.proxy(this.click, this))
327 | .on('mouseenter', 'li', $.proxy(this.mouseenter, this))
328 | .on('mouseleave', 'li', $.proxy(this.mouseleave, this))
329 | .on('mousedown', $.proxy(this.mousedown,this));
330 | },
331 |
332 | mousedown: function(e) {
333 | this.mouseddown=true;
334 | e.stopPropagation();
335 | e.preventDefault();
336 | },
337 |
338 | destroy : function () {
339 | this.$element.data('typeahead',null);
340 | this.$element.data('active',null);
341 | this.$element
342 | .off('focus')
343 | .off('blur')
344 | .off('keypress')
345 | .off('input')
346 | .off('keyup');
347 |
348 | if (this.eventSupported('keydown')) {
349 | this.$element.off('keydown');
350 | }
351 |
352 | this.$menu.remove();
353 | },
354 |
355 | eventSupported: function(eventName) {
356 | var isSupported = eventName in this.$element;
357 | if (!isSupported) {
358 | this.$element.setAttribute(eventName, 'return;');
359 | isSupported = typeof this.$element[eventName] === 'function';
360 | }
361 | return isSupported;
362 | },
363 |
364 | move: function (e) {
365 | if (!this.shown) return;
366 |
367 | switch(e.keyCode) {
368 | case 9: // tab
369 | case 13: // enter
370 | case 27: // escape
371 | e.preventDefault();
372 | break;
373 |
374 | case 38: // up arrow
375 | // with the shiftKey (this is actually the left parenthesis)
376 | if (e.shiftKey) return;
377 | e.preventDefault();
378 | this.prev();
379 | break;
380 |
381 | case 40: // down arrow
382 | // with the shiftKey (this is actually the right parenthesis)
383 | if (e.shiftKey) return;
384 | e.preventDefault();
385 | this.next();
386 | break;
387 | }
388 | },
389 |
390 | keydown: function (e) {
391 | this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27]);
392 | if (!this.shown && e.keyCode == 40) {
393 | this.lookup();
394 | } else {
395 | this.move(e);
396 | }
397 | },
398 |
399 | keypress: function (e) {
400 | if (this.suppressKeyPressRepeat) return;
401 | this.move(e);
402 | },
403 |
404 | input: function (e) {
405 | this.lookup();
406 | e.preventDefault();
407 | },
408 |
409 | keyup: function (e) {
410 | switch(e.keyCode) {
411 | case 40: // down arrow
412 | case 38: // up arrow
413 | case 16: // shift
414 | case 17: // ctrl
415 | case 18: // alt
416 | break;
417 |
418 | case 9: // tab
419 | case 13: // enter
420 | if (!this.shown) return;
421 | this.select();
422 | break;
423 |
424 | case 27: // escape
425 | if (!this.shown) return;
426 | this.hide();
427 | break;
428 | }
429 |
430 | e.preventDefault();
431 | },
432 |
433 | focus: function (e) {
434 | if (!this.focused) {
435 | this.focused = true;
436 | if (this.options.showHintOnFocus) {
437 | this.lookup();
438 | }
439 | }
440 | },
441 |
442 | blur: function (e) {
443 | this.focused = false;
444 | if (!this.mousedover && this.shown) {
445 | if(this.mouseddown && e.originalEvent){
446 | this.mouseddown=false;
447 | }else{
448 | this.hide();
449 | }
450 |
451 | }
452 |
453 | },
454 |
455 | click: function (e) {
456 | e.preventDefault();
457 | this.select();
458 | this.$element.focus();
459 | this.hide();
460 | },
461 |
462 | mouseenter: function (e) {
463 | this.mousedover = true;
464 | this.$menu.find('.active').removeClass('active');
465 | $(e.currentTarget).addClass('active');
466 | },
467 |
468 | mouseleave: function (e) {
469 | this.mousedover = false;
470 | /*if (!this.focused && this.shown) this.hide();*/
471 | }
472 |
473 | };
474 |
475 |
476 | /* TYPEAHEAD PLUGIN DEFINITION
477 | * =========================== */
478 |
479 | var old = $.fn.typeahead;
480 |
481 | $.fn.typeahead = function (option) {
482 | var arg = arguments;
483 | if (typeof option == 'string' && option == 'getActive') {
484 | return this.data('active');
485 | }
486 | return this.each(function () {
487 | var $this = $(this)
488 | , data = $this.data('typeahead')
489 | , options = typeof option == 'object' && option;
490 | if (!data) $this.data('typeahead', (data = new Typeahead(this, options)));
491 | if (typeof option == 'string' && data[option]) {
492 | if (arg.length > 1) {
493 | data[option].apply(data, Array.prototype.slice.call(arg ,1));
494 | } else {
495 | data[option]();
496 | }
497 | }
498 | });
499 | };
500 |
501 | $.fn.typeahead.defaults = {
502 | source: [],
503 | items: 8,
504 | menu: '',
505 | item: '',
506 | minLength: 1,
507 | scrollHeight: 0,
508 | autoSelect: true,
509 | afterSelect: $.noop,
510 | addItem: false,
511 | delay: 0,
512 | separator: 'category',
513 | headerHtml: '',
514 | headerDivider: ''
515 | };
516 |
517 | $.fn.typeahead.Constructor = Typeahead;
518 |
519 |
520 | /* TYPEAHEAD NO CONFLICT
521 | * =================== */
522 |
523 | $.fn.typeahead.noConflict = function () {
524 | $.fn.typeahead = old;
525 | return this;
526 | };
527 |
528 |
529 | /* TYPEAHEAD DATA-API
530 | * ================== */
531 |
532 | $(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
533 | var $this = $(this);
534 | if ($this.data('typeahead')) return;
535 | $this.typeahead($this.data());
536 | });
537 |
538 | }));
539 |
540 |
--------------------------------------------------------------------------------
/src/config/editor/js/fileupload.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery HTML5 File Upload
3 | *
4 | * Author: timdream at gmail.com
5 | * Web: http://timc.idv.tw/html5-file-upload/
6 | *
7 | * Ajax File Upload that use real xhr,
8 | * built with getAsBinary, sendAsBinary, FormData, FileReader, ArrayBuffer, BlobBuilder and etc.
9 | * works in Firefox 3, Chrome 5, Safari 5 and higher
10 | *
11 | * Image resizing and uploading currently works in Fx 3 and up, and Chrome 9 (dev) and up only.
12 | * Extra settings will allow current Webkit users to upload the original image
13 | * or send the resized image in base64 form.
14 | *
15 | * Usage:
16 | * $.fileUploadSupported // a boolean value indicates if the browser is supported.
17 | * $.imageUploadSupported // a boolean value indicates if the browser could resize image and upload in binary form.
18 | * $.fileUploadAsBase64Supported // a boolean value indicate if the browser upload files in based64.
19 | * $.imageUploadAsBase64Supported // a boolean value indicate if the browser could resize image and upload in based64.
20 | * $('input[type=file]').fileUpload(ajaxSettings); //Make a input[type=file] select-and-send file upload widget
21 | * $('#any-element').fileUpload(ajaxSettings); //Make a element receive dropped file
22 | * //TBD $('form#fileupload').fileUpload(ajaxSettings); //Send a ajax form with file
23 | * //TBD $('canvas').fileUpload(ajaxSettings); //Upload given canvas as if it's an png image.
24 | *
25 | * ajaxSettings is the object contains $.ajax settings that will be passed to.
26 | * Available extended settings are:
27 | * fileType:
28 | * regexp check against filename extension; You should always checked it again on server-side.
29 | * e.g. /^(gif|jpe?g|png|tiff?)$/i for images
30 | * fileMaxSize:
31 | * Maxium file size allowed in bytes. Use scientific notation for converience.
32 | * e.g. 1E4 for 1KB, 1E8 for 1MB, 1E9 for 10MB.
33 | * If you really care the difference between 1024 and 1000, use Math.pow(2, 10)
34 | * fileError(info, textStatus, textDescription):
35 | * callback function when there is any error preventing file upload to start,
36 | * $.ajax and ajax events won't be called when error.
37 | * Use $.noop to overwrite default alert function.
38 | * imageMaxWidth, imageMaxHeight:
39 | * Use any of the two settings to enable client-size image resizing.
40 | * Image will be resized to fit into given rectangle.
41 | * File size and type limit checking will be ignored.
42 | * allowUploadOriginalImage:
43 | * Set to true if you accept original image to be uploaded as a fallback
44 | * when image resizing functionality is not available (such as Webkit browsers).
45 | * File size and type limit will be enforced.
46 | * allowDataInBase64:
47 | * Alternatively, you may wish to resize the image anyway and send the data
48 | * in base64. The data will be 133% larger and you will need to process it further with
49 | * server-side script.
50 | * This setting might work with browsers which could read file but cannot send it in original
51 | * binary (no known browser are designed this way though)
52 | * forceResize:
53 | * Set to true will cause the image being re-sampled even if the resized image
54 | * has the same demension as the original one.
55 | * imageType:
56 | * Acceptable values are: 'jpeg', 'png', or 'auto'.
57 | *
58 | * TBD:
59 | * ability to change settings after binding (you can unbind and bind again as a workaround)
60 | * multipole file handling
61 | * form intergation
62 | *
63 | */
64 |
65 | (function() {
66 | // Don't do logging if window.log function does not exist.
67 | var log = window.log || $.noop;
68 |
69 | // jQuery.ajax config
70 | var config = {
71 | fileError: function (info, textStatus, textDescription) {
72 | window.alert(textDescription);
73 | }
74 | };
75 |
76 | // Feature detection
77 |
78 | // Read as binary string: FileReader API || Gecko-specific function (Fx3)
79 | var canReadAsBinaryString = (window.FileReader || (window.File && window.File.prototype.getAsBinary));
80 | // Read file using FormData interface
81 | var canReadFormData = !!(window.FormData);
82 | // Read file into data: URL: FileReader API || Gecko-specific function (Fx3)
83 | var canReadAsBase64 = (window.FileReader || (window.File && window.File.prototype.getAsDataURL));
84 |
85 | var canResizeImageToBase64 = !!(document.createElement('canvas').toDataURL);
86 | var canResizeImageToBinaryString = canResizeImageToBase64 && window.atob;
87 | var canResizeImageToFile = !!(document.createElement('canvas').mozGetAsFile);
88 |
89 | // Send file in multipart/form-data with binary xhr (Gecko-specific function)
90 | // || xhr.send(blob) that sends blob made with ArrayBuffer.
91 | var canSendBinaryString = (
92 | (window.XMLHttpRequest && window.XMLHttpRequest.prototype.sendAsBinary)
93 | || (window.Blob && window.Uint8Array && window.ProgressEvent)
94 | || (window.ArrayBuffer && window.BlobBuilder)
95 | );
96 | // Send file as in FormData object
97 | var canSendFormData = !!(window.FormData);
98 | // Send image base64 data by extracting data: URL
99 | var canSendImageInBase64 = !!(document.createElement('canvas').toDataURL);
100 |
101 | var isSupported = (
102 | (canReadAsBinaryString && canSendBinaryString)
103 | || (canReadFormData && canSendFormData)
104 | );
105 | var isImageSupported = (
106 | canReadAsBase64 && (
107 | (canResizeImageToBinaryString && canSendBinaryString)
108 | || (canResizeImageToFile && canSendFormData)
109 | )
110 | );
111 | var isSupportedInBase64 = canReadAsBase64;
112 | var isImageSupportedInBase64 = canReadAsBase64 && canResizeImageToBase64;
113 |
114 | var dataURLtoBase64 = function (dataurl) {
115 | return dataurl.substring(dataurl.indexOf(',')+1, dataurl.length);
116 | }
117 |
118 | // Step 1: check file info and attempt to read the file
119 | // paramaters: Ajax settings, File object
120 | var handleFile = function (settings, file) {
121 | var info = {
122 | // properties of standard File object || Gecko 1.9 properties
123 | type: file.type || '', // MIME type
124 | size: file.size || file.fileSize,
125 | name: file.name || file.fileName
126 | };
127 |
128 | // settings.resizeImage = !!(settings.imageMaxWidth || settings.imageMaxHeight);
129 |
130 | if (settings.resizeImage && !isImageSupported && settings.allowUploadOriginalImage) {
131 | log('WARN: Fall back to upload original un-resized image.');
132 | settings.resizeImage = false;
133 | }
134 |
135 | /*
136 | if (settings.resizeImage) {
137 | settings.imageMaxWidth = settings.imageMaxWidth || Infinity;
138 | settings.imageMaxHeight = settings.imageMaxHeight || Infinity;
139 | }
140 | */
141 |
142 | if (!settings.resizeImage) {
143 | if (settings.fileType && settings.fileType.test) {
144 | // Not using MIME types
145 | if (!settings.fileType.test(info.name.substr(info.name.lastIndexOf('.')+1))) {
146 | log('ERROR: Invalid Filetype.');
147 | settings.fileError.call(this, info, 'INVALID_FILETYPE', 'Invalid filetype.');
148 | return;
149 | }
150 | }
151 |
152 | if (settings.fileMaxSize && file.size > settings.fileMaxSize) {
153 | log('ERROR: File exceeds size limit.');
154 | settings.fileError.call(this, info, 'FILE_EXCEEDS_SIZE_LIMIT', 'File exceeds size limit.');
155 | return;
156 | }
157 | }
158 |
159 | if (!settings.resizeImage && canReadFormData) {
160 | log('INFO: Bypass file reading, insert file object into FormData object directly.');
161 | handleForm(settings, 'file', file, info);
162 | } else if (window.FileReader) {
163 | log('INFO: Using FileReader to do asynchronously file reading.');
164 | var reader = new FileReader();
165 | reader.onerror = function (ev) {
166 | if (ev.target.error) {
167 | switch (ev.target.error) {
168 | case 8:
169 | log('ERROR: File not found.');
170 | settings.fileError.call(this, info, 'FILE_NOT_FOUND', 'File not found.');
171 | break;
172 | case 24:
173 | log('ERROR: File not readable.');
174 | settings.fileError.call(this, info, 'IO_ERROR', 'File not readable.');
175 | break;
176 | case 18:
177 | log('ERROR: File cannot be access due to security constrant.');
178 | settings.fileError.call(this, info, 'SECURITY_ERROR', 'File cannot be access due to security constrant.');
179 | break;
180 | case 20: //User Abort
181 | break;
182 | }
183 | }
184 | }
185 | if (!settings.resizeImage) {
186 | if (canSendBinaryString) {
187 | reader.onloadend = function (ev) {
188 | var bin = ev.target.result;
189 | handleForm(settings, 'bin', bin, info);
190 | };
191 | reader.readAsBinaryString(file);
192 | } else if (settings.allowDataInBase64) {
193 | reader.onloadend = function (ev) {
194 | handleForm(
195 | settings,
196 | 'base64',
197 | dataURLtoBase64(ev.target.result),
198 | info
199 | );
200 | };
201 | reader.readAsDataURL(file);
202 | } else {
203 | log('ERROR: No available method to extract file; allowDataInBase64 not set.');
204 | settings.fileError.call(this, info, 'NO_BIN_SUPPORT_AND_BASE64_NOT_SET', 'No available method to extract file; allowDataInBase64 not set.');
205 | }
206 | } else {
207 | reader.onloadend = function (ev) {
208 | var dataurl = ev.target.result;
209 | handleImage(settings, dataurl, info, file);
210 | };
211 | reader.readAsDataURL(file);
212 | }
213 | } else if (window.File && window.File.prototype.getAsBinary) {
214 | log('WARN: FileReader does not exist, UI will be blocked when reading big file.');
215 | if (!settings.resizeImage) {
216 | try {
217 | var bin = file.getAsBinary();
218 | } catch (e) {
219 | log('ERROR: File not readable.');
220 | settings.fileError.call(this, info, 'IO_ERROR', 'File not readable.');
221 | return;
222 | }
223 | handleForm(settings, 'bin', bin, info);
224 | } else {
225 | try {
226 | var bin = file.getAsDataURL();
227 | } catch (e) {
228 | log('ERROR: File not readable.');
229 | settings.fileError.call(this, info, 'IO_ERROR', 'File not readable.');
230 | return;
231 | }
232 | handleImage(settings, dataurl, info, file);
233 | }
234 | } else {
235 | // log('ERROR: No available method to extract file; this browser is not supported.');
236 | if (settings.fallback) {
237 | settings.fallback();
238 | } else {
239 | settings.fileError.call(this, info, 'NOT_SUPPORT', 'ERROR: No available method to extract file; this browser is not supported.');
240 | }
241 | }
242 | };
243 |
244 | // step 1.5: inject file into
, paste the pixels into