Version Description
- WP TinyMCE editor support
- HTML editor with CodeMirror as a TinyMCE plugin
- Live preview (> WP 3.1)
- Include filter to add your own tag replacements
- Help moved to contextual help
- Translations for german, hebrew
- Improved template email clients support
Download this release
Release Info
Developer | nlemoine |
Plugin | WP Better Emails |
Version | 0.2 |
Comparing to | |
See all releases |
Code changes from version 0.1.3 to 0.2
- css/wpbe-admin-style.css +24 -54
- email_template.php +0 -49
- js/jquery.cookie.js +0 -96
- js/wpbe-admin-script.js +42 -17
- langs/wp-better-emails-de_DE.mo +0 -0
- langs/wp-better-emails-de_DE.po +196 -0
- langs/wp-better-emails-fr_FR.mo +0 -0
- langs/wp-better-emails-fr_FR.po +124 -164
- langs/wp-better-emails-he_IL.mo +0 -0
- langs/wp-better-emails-he_IL.po +197 -0
- langs/wp-better-emails-nl_NL.mo +0 -0
- langs/wp-better-emails-nl_NL.po +0 -236
- langs/wp-better-emails.mo +0 -0
- langs/wp-better-emails.pot +105 -144
- markitup/jquery.markitup.js +0 -565
- markitup/sets/html/images/bold.png +0 -0
- markitup/sets/html/images/clean.png +0 -0
- markitup/sets/html/images/h1.png +0 -0
- markitup/sets/html/images/h2.png +0 -0
- markitup/sets/html/images/h3.png +0 -0
- markitup/sets/html/images/h4.png +0 -0
- markitup/sets/html/images/h5.png +0 -0
- markitup/sets/html/images/h6.png +0 -0
- markitup/sets/html/images/image.png +0 -0
- markitup/sets/html/images/italic.png +0 -0
- markitup/sets/html/images/link.png +0 -0
- markitup/sets/html/images/list-bullet.png +0 -0
- markitup/sets/html/images/list-item.png +0 -0
- markitup/sets/html/images/list-numeric.png +0 -0
- markitup/sets/html/images/paragraph.png +0 -0
- markitup/sets/html/images/picture.png +0 -0
- markitup/sets/html/images/preview.png +0 -0
- markitup/sets/html/images/stroke.png +0 -0
- markitup/sets/html/readme.txt +0 -11
- markitup/sets/html/set.js +0 -39
- markitup/sets/html/style.css +0 -59
- markitup/skins/markitup/images/bg-container.png +0 -0
- markitup/skins/markitup/images/bg-editor-bbcode.png +0 -0
- markitup/skins/markitup/images/bg-editor-dotclear.png +0 -0
- markitup/skins/markitup/images/bg-editor-html.png +0 -0
- markitup/skins/markitup/images/bg-editor-json.png +0 -0
- markitup/skins/markitup/images/bg-editor-markdown.png +0 -0
- markitup/skins/markitup/images/bg-editor-textile.png +0 -0
- markitup/skins/markitup/images/bg-editor-wiki.png +0 -0
- markitup/skins/markitup/images/bg-editor-xml.png +0 -0
- markitup/skins/markitup/images/bg-editor.png +0 -0
- markitup/skins/markitup/images/handle.png +0 -0
- markitup/skins/markitup/images/menu.png +0 -0
- markitup/skins/markitup/images/submenu.png +0 -0
- markitup/skins/markitup/style.css +0 -147
- markitup/skins/simple/images/handle.png +0 -0
- markitup/skins/simple/images/menu.png +0 -0
- markitup/skins/simple/images/submenu.png +0 -0
- markitup/skins/simple/style.css +0 -118
- markitup/templates/preview.html +0 -1
- preview.html +0 -0
- readme.txt +76 -22
- screenshot-1.png +0 -0
- screenshot-2.png +0 -0
- screenshot-3.png +0 -0
- screenshot-4.png +0 -0
- screenshot-5.png +0 -0
- templates/template-1.html +61 -0
- templates/template-1.php +56 -0
- tinymce-plugins/3.3.x/fullpage/css/fullpage.css +182 -0
- tinymce-plugins/3.3.x/fullpage/editor_plugin.js +1 -0
- tinymce-plugins/3.3.x/fullpage/editor_plugin_src.js +182 -0
- tinymce-plugins/3.3.x/fullpage/fullpage.htm +571 -0
- tinymce-plugins/3.3.x/fullpage/js/fullpage.js +471 -0
- tinymce-plugins/3.3.x/fullpage/langs/en_dlg.js +85 -0
- tinymce-plugins/3.4.x/fullpage/css/fullpage.css +143 -0
- tinymce-plugins/3.4.x/fullpage/editor_plugin.js +1 -0
- tinymce-plugins/3.4.x/fullpage/editor_plugin_src.js +399 -0
- tinymce-plugins/3.4.x/fullpage/fullpage.htm +259 -0
- tinymce-plugins/3.4.x/fullpage/js/fullpage.js +232 -0
- tinymce-plugins/3.4.x/fullpage/langs/en_dlg.js +85 -0
- tinymce-plugins/cmseditor/editor_plugin.js +84 -0
- tinymce-plugins/cmseditor/img/ed-bg.gif +0 -0
- tinymce-plugins/cmseditor/img/html.gif +0 -0
- tinymce-plugins/cmseditor/js/LICENSE +19 -0
- tinymce-plugins/cmseditor/js/README.md +6 -0
- tinymce-plugins/cmseditor/js/codemirror-compressed.js +1 -0
- tinymce-plugins/cmseditor/js/lib/codemirror.css +82 -0
- tinymce-plugins/cmseditor/js/lib/codemirror.js +2157 -0
- tinymce-plugins/cmseditor/js/lib/overlay.js +51 -0
- tinymce-plugins/cmseditor/js/lib/runmode.js +27 -0
- tinymce-plugins/cmseditor/js/mode/css/css.js +124 -0
- tinymce-plugins/cmseditor/js/mode/css/index.html +56 -0
- tinymce-plugins/cmseditor/js/mode/htmlmixed/htmlmixed.js +79 -0
- tinymce-plugins/cmseditor/js/mode/htmlmixed/index.html +52 -0
- tinymce-plugins/cmseditor/js/mode/javascript/index.html +78 -0
- tinymce-plugins/cmseditor/js/mode/javascript/javascript.js +348 -0
- tinymce-plugins/cmseditor/js/mode/php/index.html +49 -0
- tinymce-plugins/cmseditor/js/mode/php/php.js +115 -0
- tinymce-plugins/cmseditor/js/mode/xml/index.html +42 -0
- tinymce-plugins/cmseditor/js/mode/xml/xml.js +231 -0
- tinymce-plugins/cmseditor/js/mode/xmlpure/index.html +60 -0
- tinymce-plugins/cmseditor/js/mode/xmlpure/xmlpure.js +481 -0
- tinymce-plugins/cmseditor/js/theme/default.css +19 -0
- tinymce-plugins/cmseditor/js/theme/elegant.css +9 -0
- tinymce-plugins/cmseditor/js/theme/neat.css +8 -0
- tinymce-plugins/cmseditor/js/theme/night.css +20 -0
- tinymce-plugins/cmseditor/langs/en.js +3 -0
- tinymce-plugins/cmseditor/langs/en_dlg.js +3 -0
- wpbe-options.php +45 -77
- wpbe.php +495 -301
- wpbe_template.html +0 -47
css/wpbe-admin-style.css
CHANGED
@@ -1,57 +1,27 @@
|
|
1 |
-
#wpbe_options_tabs {
|
2 |
-
overflow: hidden;
|
3 |
-
height: 100%;
|
4 |
-
margin: 20px 0;
|
5 |
-
}
|
6 |
-
#wpbe_options_tabs .wpbe_tabs_titles {
|
7 |
-
float: left;
|
8 |
-
width: 97%;
|
9 |
-
height: 32px;
|
10 |
-
margin: 0 0 20px 0;
|
11 |
-
padding: 0 0 0 15px;
|
12 |
-
border-bottom: solid 1px #ccc;
|
13 |
-
}
|
14 |
-
#wpbe_options_tabs .wpbe_tabs_titles li {
|
15 |
-
float: left;
|
16 |
-
height: 31px;
|
17 |
-
line-height: 31px;
|
18 |
-
padding: 0;
|
19 |
-
margin: 0 3px 0 0;
|
20 |
-
border: solid 1px #ccc;
|
21 |
-
background: #fff;
|
22 |
-
-moz-border-radius: 4px 4px 0 0;
|
23 |
-
-webkit-border-radius: 4px 4px 0 0;
|
24 |
-
border-radius: 4px 4px 0 0;
|
25 |
-
}
|
26 |
-
#wpbe_options_tabs .wpbe_tabs_titles a {
|
27 |
-
color: #ccc;
|
28 |
-
text-decoration: none;
|
29 |
-
font-size: 14px;
|
30 |
-
display: block;
|
31 |
-
padding: 0 20px;
|
32 |
-
border-bottom: none;
|
33 |
-
}
|
34 |
-
#wpbe_options_tabs ul li.ui-state-active {
|
35 |
-
background: #f9f9f9;
|
36 |
-
border-bottom: 1px solid #f9f9f9;
|
37 |
-
}
|
38 |
-
#wpbe_options_tabs .ui-state-active a {
|
39 |
-
color: #333;
|
40 |
-
}
|
41 |
-
#wpbe_options_tabs .ui-state-active a:hover,
|
42 |
-
#wpbe_options_tabs a:hover {
|
43 |
-
color: #D54E21;
|
44 |
-
}
|
45 |
-
.wpbe_tab_content {
|
46 |
-
padding: 0 20px;
|
47 |
-
}
|
48 |
-
.markItUpPreviewFrame {
|
49 |
-
border: solid 1px #ddd;
|
50 |
-
}
|
51 |
#wpbe_preview_email {
|
52 |
-
|
53 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
}
|
55 |
-
#
|
56 |
-
|
57 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
#wpbe_preview_email {
|
2 |
+
vertical-align: middle;
|
3 |
+
}
|
4 |
+
#wpbe_ajax_loading {
|
5 |
+
vertical-align: middle;
|
6 |
+
}
|
7 |
+
#wpbe_preview_message {
|
8 |
+
width: 80%;
|
9 |
+
}
|
10 |
+
#wpbe_support {
|
11 |
+
color: #777;
|
12 |
+
border-top: solid 1px #DFDFDF;
|
13 |
+
}
|
14 |
+
#wpbe_template_tbl {
|
15 |
+
border: solid 1px #ccc;
|
16 |
+
overflow: auto;
|
17 |
+
}
|
18 |
+
#wpbe_template {
|
19 |
+
width: 100%;
|
20 |
+
height: 410px;
|
21 |
+
}
|
22 |
+
#wpbe_template_container {
|
23 |
+
width: 80%;
|
24 |
}
|
25 |
+
#wpbe_preview_template {
|
26 |
+
font-weight: normal;
|
27 |
}
|
email_template.php
DELETED
@@ -1,49 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
$template = '<html>
|
3 |
-
<body bgcolor="#f9f9f9" link="#21759B" alink="#21759B" vlink="#21759B" marginheight="0" topmargin="0" marginwidth="0" leftmargin="0" style="margin: 0px; background-color: #f9f9f9; font-family: Helvetica, Arial, sans-serif;">
|
4 |
-
<table cellpadding="0" cellspacing="0" width="100%" bgcolor="#f9f9f9" border="0">
|
5 |
-
<tr>
|
6 |
-
<td style="padding:15px;" align="center">
|
7 |
-
<center>
|
8 |
-
<table width="550" cellpadding="0" bgcolor="#ffffff" cellspacing="0" >
|
9 |
-
<tr>
|
10 |
-
<td>
|
11 |
-
<div style="border:solid 1px #d9d9d9;">
|
12 |
-
<table id="header" width="100%;" border="0" cellpadding="0" bgcolor="#ffffff" cellspacing="0" style="line-height:1.5;font-size:12px;font-family: Helvetica, Arial, sans-serif;border:solid 1px #FFFFFF;">
|
13 |
-
<tr>
|
14 |
-
<td colspan="2" background="%blog_url%/wp-admin/images/white-grad-active.png" height="30"> </td>
|
15 |
-
</tr>
|
16 |
-
<tr >
|
17 |
-
<td style="line-height:32px;padding: 0 0 0 30px;" valign="baseline">
|
18 |
-
<span style="font-size:32px;"><a href="%blog_url%" style="text-decoration:none;" target="_blank">%blog_name%</a></span>
|
19 |
-
</td>
|
20 |
-
<td style="padding: 0 30px 0 0;" align="right" valign="baseline">
|
21 |
-
<span style="font-size:14px;color:#777777">%blog_description%</span>
|
22 |
-
</td>
|
23 |
-
</tr>
|
24 |
-
</table>
|
25 |
-
<table id="content" width="100%;" border="0" cellpadding="0" bgcolor="#ffffff" cellspacing="0" style="color:#444;line-height:1.5;font-size:12px;font-family: Arial, sans-serif;padding:20px 30px 0 30px;">
|
26 |
-
<tr>
|
27 |
-
<td colspan="2" style="padding:20px 0;border-top: solid 1px #d9d9d9">%content%</td>
|
28 |
-
</tr>
|
29 |
-
</table>
|
30 |
-
<table id="footer" width="100%;" border="0" cellpadding="0" bgcolor="#ffffff" cellspacing="0" style="line-height:1.5;font-size:12px;font-family: Arial, sans-serif;padding:0 30px 15px 30px;">
|
31 |
-
<tr style="font-size:11px;color:#777777;">
|
32 |
-
<td style="border-top: solid 1px #d9d9d9;" colspan="2">
|
33 |
-
<img style="padding:15px 0 0 0" height="32" width="32" src="%blog_url%/wp-admin/images/wp-logo.png" align="right" alt="' . __('Powered by Wordpress', 'wpbe') . '" />
|
34 |
-
<div style="padding:15px 0 1px 0"><img height="13" width="13" style="vertical-align: middle;" src="%blog_url%/wp-admin/images/date-button.gif" alt="' . __('Date') . '" /> ' . __('Email sent the', 'wpbe') . ' %date% @ %time%</div>
|
35 |
-
<div><img height="12" width="12" style="vertical-align: middle;" src="%blog_url%/wp-admin/images/comment-grey-bubble.png" alt="' . __('Contact') . '" /> ' . __('For any request, please contact', 'wpbe') . ' <a href="mailto:%admin_email%">%admin_email%</a></div>
|
36 |
-
</td>
|
37 |
-
</tr>
|
38 |
-
</table>
|
39 |
-
</div>
|
40 |
-
</td>
|
41 |
-
</tr>
|
42 |
-
</table>
|
43 |
-
</center>
|
44 |
-
</td>
|
45 |
-
</tr>
|
46 |
-
</table>
|
47 |
-
</body>
|
48 |
-
</html>';
|
49 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
js/jquery.cookie.js
DELETED
@@ -1,96 +0,0 @@
|
|
1 |
-
/**
|
2 |
-
* Cookie plugin
|
3 |
-
*
|
4 |
-
* Copyright (c) 2006 Klaus Hartl (stilbuero.de)
|
5 |
-
* Dual licensed under the MIT and GPL licenses:
|
6 |
-
* http://www.opensource.org/licenses/mit-license.php
|
7 |
-
* http://www.gnu.org/licenses/gpl.html
|
8 |
-
*
|
9 |
-
*/
|
10 |
-
|
11 |
-
/**
|
12 |
-
* Create a cookie with the given name and value and other optional parameters.
|
13 |
-
*
|
14 |
-
* @example $.cookie('the_cookie', 'the_value');
|
15 |
-
* @desc Set the value of a cookie.
|
16 |
-
* @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
|
17 |
-
* @desc Create a cookie with all available options.
|
18 |
-
* @example $.cookie('the_cookie', 'the_value');
|
19 |
-
* @desc Create a session cookie.
|
20 |
-
* @example $.cookie('the_cookie', null);
|
21 |
-
* @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
|
22 |
-
* used when the cookie was set.
|
23 |
-
*
|
24 |
-
* @param String name The name of the cookie.
|
25 |
-
* @param String value The value of the cookie.
|
26 |
-
* @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
|
27 |
-
* @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
|
28 |
-
* If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
|
29 |
-
* If set to null or omitted, the cookie will be a session cookie and will not be retained
|
30 |
-
* when the the browser exits.
|
31 |
-
* @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
|
32 |
-
* @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
|
33 |
-
* @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
|
34 |
-
* require a secure protocol (like HTTPS).
|
35 |
-
* @type undefined
|
36 |
-
*
|
37 |
-
* @name $.cookie
|
38 |
-
* @cat Plugins/Cookie
|
39 |
-
* @author Klaus Hartl/klaus.hartl@stilbuero.de
|
40 |
-
*/
|
41 |
-
|
42 |
-
/**
|
43 |
-
* Get the value of a cookie with the given name.
|
44 |
-
*
|
45 |
-
* @example $.cookie('the_cookie');
|
46 |
-
* @desc Get the value of a cookie.
|
47 |
-
*
|
48 |
-
* @param String name The name of the cookie.
|
49 |
-
* @return The value of the cookie.
|
50 |
-
* @type String
|
51 |
-
*
|
52 |
-
* @name $.cookie
|
53 |
-
* @cat Plugins/Cookie
|
54 |
-
* @author Klaus Hartl/klaus.hartl@stilbuero.de
|
55 |
-
*/
|
56 |
-
jQuery.cookie = function(name, value, options) {
|
57 |
-
if (typeof value != 'undefined') { // name and value given, set cookie
|
58 |
-
options = options || {};
|
59 |
-
if (value === null) {
|
60 |
-
value = '';
|
61 |
-
options.expires = -1;
|
62 |
-
}
|
63 |
-
var expires = '';
|
64 |
-
if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
|
65 |
-
var date;
|
66 |
-
if (typeof options.expires == 'number') {
|
67 |
-
date = new Date();
|
68 |
-
date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
|
69 |
-
} else {
|
70 |
-
date = options.expires;
|
71 |
-
}
|
72 |
-
expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
|
73 |
-
}
|
74 |
-
// CAUTION: Needed to parenthesize options.path and options.domain
|
75 |
-
// in the following expressions, otherwise they evaluate to undefined
|
76 |
-
// in the packed version for some reason...
|
77 |
-
var path = options.path ? '; path=' + (options.path) : '';
|
78 |
-
var domain = options.domain ? '; domain=' + (options.domain) : '';
|
79 |
-
var secure = options.secure ? '; secure' : '';
|
80 |
-
document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
|
81 |
-
} else { // only name given, get cookie
|
82 |
-
var cookieValue = null;
|
83 |
-
if (document.cookie && document.cookie != '') {
|
84 |
-
var cookies = document.cookie.split(';');
|
85 |
-
for (var i = 0; i < cookies.length; i++) {
|
86 |
-
var cookie = jQuery.trim(cookies[i]);
|
87 |
-
// Does this cookie string begin with the name we want?
|
88 |
-
if (cookie.substring(0, name.length + 1) == (name + '=')) {
|
89 |
-
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
90 |
-
break;
|
91 |
-
}
|
92 |
-
}
|
93 |
-
}
|
94 |
-
return cookieValue;
|
95 |
-
}
|
96 |
-
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
js/wpbe-admin-script.js
CHANGED
@@ -1,27 +1,52 @@
|
|
1 |
-
jQuery(document).ready(function(){
|
2 |
-
// Tabs
|
3 |
-
jQuery('#wpbe_options_tabs').tabs( { cookie: { expires: 1 } } );
|
4 |
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
var preview_nonce = jQuery('#wpbe_nonce_preview').val();
|
11 |
-
jQuery.ajax({
|
12 |
type: 'post',
|
13 |
-
url:
|
14 |
data: {
|
15 |
-
action:
|
16 |
preview_email: email,
|
17 |
-
_ajax_nonce:
|
|
|
|
|
|
|
18 |
},
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
|
|
23 |
}
|
24 |
});
|
|
|
|
|
|
|
|
|
25 |
e.preventDefault();
|
|
|
26 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
});
|
1 |
+
jQuery(document).ready(function($){
|
|
|
|
|
2 |
|
3 |
+
// Send email preview
|
4 |
+
$('#wpbe_send_preview').click(function(e) {
|
5 |
+
e.preventDefault();
|
6 |
+
var email = $('#wpbe_email_preview_field').val(), message = $('#wpbe_preview_message'), loading = $('#wpbe_ajax_loading');
|
7 |
+
$.ajax({
|
|
|
|
|
8 |
type: 'post',
|
9 |
+
url: wpbe_ajax_vars.url,
|
10 |
data: {
|
11 |
+
action: wpbe_ajax_vars.action,
|
12 |
preview_email: email,
|
13 |
+
_ajax_nonce: wpbe_ajax_vars.nonce
|
14 |
+
},
|
15 |
+
beforeSend: function() {
|
16 |
+
loading.css('visibility', 'visible');
|
17 |
},
|
18 |
+
complete: function() {
|
19 |
+
loading.css('visibility', 'hidden');
|
20 |
+
},
|
21 |
+
success: function(data) {
|
22 |
+
message.append(data);
|
23 |
}
|
24 |
});
|
25 |
+
});
|
26 |
+
|
27 |
+
// Trigger help
|
28 |
+
$('#wpbe_help').bind('click', function(e){
|
29 |
e.preventDefault();
|
30 |
+
$('a#contextual-help-link').trigger('click');
|
31 |
});
|
32 |
+
|
33 |
+
// Thickbox preview
|
34 |
+
$('#wpbe_preview_template').live('click', function(e) {
|
35 |
+
e.preventDefault();
|
36 |
+
var preview_iframe = $('#TB_iframeContent');
|
37 |
+
if( preview_iframe.length ) {
|
38 |
+
var template;
|
39 |
+
if (typeof(tinyMCE) != 'undefined') {
|
40 |
+
if( tinyMCE.activeEditor && !tinyMCE.activeEditor.isHidden() )
|
41 |
+
template = tinyMCE.activeEditor.getContent();
|
42 |
+
else
|
43 |
+
template = $('.wpbe_template').val();
|
44 |
+
}
|
45 |
+
preview_iframe = preview_iframe[preview_iframe.length - 1].contentWindow || frame[preview_iframe.length - 1];
|
46 |
+
preview_iframe.document.open();
|
47 |
+
preview_iframe.document.write( template );
|
48 |
+
preview_iframe.document.close();
|
49 |
+
}
|
50 |
+
});
|
51 |
+
|
52 |
});
|
langs/wp-better-emails-de_DE.mo
ADDED
Binary file
|
langs/wp-better-emails-de_DE.po
ADDED
@@ -0,0 +1,196 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Copyright (C) 2010
|
2 |
+
# This file is distributed under the same license as the package.
|
3 |
+
msgid ""
|
4 |
+
msgstr ""
|
5 |
+
"Project-Id-Version: WP Better Emails\n"
|
6 |
+
"Report-Msgid-Bugs-To: http://wordpress.org/tag/wp-better-emails\n"
|
7 |
+
"POT-Creation-Date: 2011-09-06 23:22:41+00:00\n"
|
8 |
+
"MIME-Version: 1.0\n"
|
9 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
10 |
+
"Content-Transfer-Encoding: 8bit\n"
|
11 |
+
"PO-Revision-Date: 2011-09-12 17:26+0100\n"
|
12 |
+
"Last-Translator: \n"
|
13 |
+
"Language-Team: Robert Tremmel <robert.tremmel@gmx.net>\n"
|
14 |
+
"X-Poedit-Language: German\n"
|
15 |
+
|
16 |
+
#: wpbe-options.php:2
|
17 |
+
#: wpbe.php:158
|
18 |
+
msgid "Email settings"
|
19 |
+
msgstr "E-Mail-Einstellungen"
|
20 |
+
|
21 |
+
#: wpbe-options.php:9
|
22 |
+
msgid "Set your own sender name and email address. Default Wordpress values will be used if empty."
|
23 |
+
msgstr "Bitte den Name des Absenders und E-Mail-Adresse eintragen. Bei leeren Feldern werden die Standard-Wordpress-Einstellungen benutzt."
|
24 |
+
|
25 |
+
#: wpbe-options.php:12
|
26 |
+
msgid "Name"
|
27 |
+
msgstr "Name des Absenders"
|
28 |
+
|
29 |
+
#: wpbe-options.php:16
|
30 |
+
msgid "Email address"
|
31 |
+
msgstr "E-Mail des Absenders"
|
32 |
+
|
33 |
+
#: wpbe-options.php:22
|
34 |
+
msgid "HTML Template"
|
35 |
+
msgstr "HTML Design-Vorlage"
|
36 |
+
|
37 |
+
#: wpbe-options.php:24
|
38 |
+
msgid "Live template preview"
|
39 |
+
msgstr "Vorschau"
|
40 |
+
|
41 |
+
#: wpbe-options.php:24
|
42 |
+
msgid "Live preview"
|
43 |
+
msgstr "Vorschau"
|
44 |
+
|
45 |
+
#: wpbe-options.php:26
|
46 |
+
msgid "Edit the HTML email template if you want to customize it. You might have a look at the <a href=\"#\" id=\"wpbe_help\">help tab</a> for further information."
|
47 |
+
msgstr "Es steht Ihnen frei, die E-Mail-HTML-Designvorlage für Ihre eigenen Zwecke zu bearbeiten. Nutzen Sie dazu auch die weiteren Informationen im Hilfe-Tab."
|
48 |
+
|
49 |
+
#: wpbe-options.php:35
|
50 |
+
msgid "Send an email preview to"
|
51 |
+
msgstr "Aktuelle Vorschau als E-Mail"
|
52 |
+
|
53 |
+
#: wpbe-options.php:39
|
54 |
+
msgid "Send"
|
55 |
+
msgstr "Absenden"
|
56 |
+
|
57 |
+
#: wpbe-options.php:41
|
58 |
+
msgid "You must save your template before sending an email preview."
|
59 |
+
msgstr "Design-Vorlage bitte vor dem Absenden speichern."
|
60 |
+
|
61 |
+
#: wpbe-options.php:46
|
62 |
+
msgid "Save Changes"
|
63 |
+
msgstr "Änderungen speichern"
|
64 |
+
|
65 |
+
#: wpbe-options.php:52
|
66 |
+
msgid "Support & bug report"
|
67 |
+
msgstr "Hilfe & Fehlerreport"
|
68 |
+
|
69 |
+
#: wpbe-options.php:53
|
70 |
+
msgid "If you have any idea to improve this plugin or any bug to report, please email me at : <a href=\"mailto:plugins@artyshow-studio.fr?subject=[wp-better-emails]\">plugins@artyshow-studio.fr</a>"
|
71 |
+
msgstr "Sie haben einen Vorschlag zur Verbesserung des Plug-ins oder möchten einen Fehler melden? Bitte senden Sie eine E-Mail an: <a href=\"mailto:plugins@artyshow-studio.fr?subject=[wp-better-emails]\">plugins@artyshow-studio.fr</a>"
|
72 |
+
|
73 |
+
#: wpbe-options.php:55
|
74 |
+
msgid "You like this plugin ? You use it in a business context ? Please, consider a <a href=\"%s\" target=\"_blank\" rel=\"external\">donation</a>."
|
75 |
+
msgstr "Gefällt Ihnen dieses Plug-in? Nutzen Sie es für gewerbliche Zwecke? Ich freue mich über Ihre Spende. <a href=\"%s\" target=\"_blank\" rel=\"external\">Jetzt spenden</a>."
|
76 |
+
|
77 |
+
#: templates/template-1.php:33
|
78 |
+
msgid "Date"
|
79 |
+
msgstr "Datum"
|
80 |
+
|
81 |
+
#: templates/template-1.php:33
|
82 |
+
msgid "Email sent"
|
83 |
+
msgstr "Die E-Mail wurde versandt am"
|
84 |
+
|
85 |
+
#: templates/template-1.php:34
|
86 |
+
msgid "Contact"
|
87 |
+
msgstr "Kontakt"
|
88 |
+
|
89 |
+
#: templates/template-1.php:34
|
90 |
+
msgid "For any requests, please contact"
|
91 |
+
msgstr "Für Fragen und Hilfe wenden Sie sich bitte an:"
|
92 |
+
|
93 |
+
#: wpbe.php:131
|
94 |
+
msgid "Settings"
|
95 |
+
msgstr "Einstellungen"
|
96 |
+
|
97 |
+
#: wpbe.php:147
|
98 |
+
msgid "WP Better Emails requires WordPress 2.8 or newer."
|
99 |
+
msgstr "WP Better Emails benötigt Version Wordpress 2.8 oder aktueller."
|
100 |
+
|
101 |
+
#: wpbe.php:147
|
102 |
+
msgid "Upgrade your Wordpress installation."
|
103 |
+
msgstr "Wordpress aktualisieren"
|
104 |
+
|
105 |
+
#: wpbe.php:158
|
106 |
+
msgid "WP Better Emails"
|
107 |
+
msgstr "WP Better Emails"
|
108 |
+
|
109 |
+
#: wpbe.php:228
|
110 |
+
msgid "Please enter a valid sender email address."
|
111 |
+
msgstr "Bitte tragen Sie eine korrekte E-Mail-Adresse ein."
|
112 |
+
|
113 |
+
#: wpbe.php:238
|
114 |
+
msgid "Template is empty"
|
115 |
+
msgstr "Die Design-Vorlage ist leer."
|
116 |
+
|
117 |
+
#: wpbe.php:241
|
118 |
+
msgid "No content tag found. The %content% tag is required in your template"
|
119 |
+
msgstr "Kein 'Inhalt' gefunden. Es wird %content% für Ihre Design-Vorlage benötigt."
|
120 |
+
|
121 |
+
#: wpbe.php:259
|
122 |
+
msgid "Please enter an email"
|
123 |
+
msgstr "Bitte geben Sie eine korrekte E-Mail-Adresse ein"
|
124 |
+
|
125 |
+
#: wpbe.php:261
|
126 |
+
msgid "Please enter a valid email"
|
127 |
+
msgstr "Bitte geben Sie eine korrekte E-Mail-Adresse an"
|
128 |
+
|
129 |
+
#: wpbe.php:262
|
130 |
+
msgid "Hey !"
|
131 |
+
msgstr "Hey !"
|
132 |
+
|
133 |
+
#: wpbe.php:264
|
134 |
+
msgid "This is a sample email to test your HTML template."
|
135 |
+
msgstr "Das ist eine Test-E-Mail zur Vorschau Ihrer Design-Vorlage in HTML."
|
136 |
+
|
137 |
+
#: wpbe.php:266
|
138 |
+
msgid "If you're not skilled in HTML/CSS email coding, I strongly recommend to leave the default template as it is. It has been tested on various and popular email clients like Gmail, Yahoo Mail, Hotmail/Live, Thunderbird, Apple Mail, Outlook, and many more."
|
139 |
+
msgstr "Sollten Sie wenig Erfahrung mit HTML/CSS-Codes haben, empfehle ich Ihnen, die Standard-Einstellungen der Design-Vorlage beizubehalten. Es wurde in gebräuchlichen E-Mail-Anwendungen getestet. Zum Beispiel: Gmail, Yahoo Mail, Hotmail/Live, Thunderbird, Apple Mail, Outlook und viele andere."
|
140 |
+
|
141 |
+
#: wpbe.php:268
|
142 |
+
msgid "If you have any problems or any suggestions to improve this plugin, please let me know."
|
143 |
+
msgstr "Sollten bei Ihnen Probleme auftreten oder haben Sie Verbesserungsvorschläge für das Plug-in? Kontaktieren Sie mich."
|
144 |
+
|
145 |
+
#: wpbe.php:269
|
146 |
+
msgid "Email template preview"
|
147 |
+
msgstr "E-Mail-Design-Vorlage in der Vorschau"
|
148 |
+
|
149 |
+
#: wpbe.php:270
|
150 |
+
msgid "An email preview has been successfully sent to %s"
|
151 |
+
msgstr "Eine E-Mail-Vorschau wurde erfolgreich an diese Adresse versandt: %s"
|
152 |
+
|
153 |
+
#: wpbe.php:273
|
154 |
+
msgid "An error occured while sending email. Please check your server configuration."
|
155 |
+
msgstr "Ein Fehler ist beim Senden der E-Mail aufgetreten. Bitte überprüfen Sie Ihre Server-Einstellungen."
|
156 |
+
|
157 |
+
#: wpbe.php:410
|
158 |
+
msgid "Some dynamic tags can be included in your email template :"
|
159 |
+
msgstr "Sie können dynamische HTML-Befehle in Ihre E-Mail-Design-Vorlage einfügen:"
|
160 |
+
|
161 |
+
#: wpbe.php:412
|
162 |
+
msgid "<strong>%content%</strong> : will be replaced with the message content."
|
163 |
+
msgstr "<strong>%content%</strong> : Wird vom Message-Text ersetzt."
|
164 |
+
|
165 |
+
#: wpbe.php:413
|
166 |
+
msgid "NOTE: The content tag is <strong>required</strong>, WP Better Emails will be automatically desactivated if no content tag is found."
|
167 |
+
msgstr "Achtung: Inhalt wird <strong>benötigt</strong>, WP Better Emails wird automatisch deaktiviert, wenn kein Inhalt gefunden wird."
|
168 |
+
|
169 |
+
#: wpbe.php:414
|
170 |
+
msgid "<strong>%blog_url%</strong> : will be replaced with your blog URL."
|
171 |
+
msgstr "<strong>%blog_url%</strong> : Ihre Blog-URL wird eingefügt."
|
172 |
+
|
173 |
+
#: wpbe.php:415
|
174 |
+
msgid "<strong>%home_url%</strong> : will be replaced with your home URL."
|
175 |
+
msgstr "<strong>%home_url%</strong> : Ihre Homepage-URL wird eingefügt."
|
176 |
+
|
177 |
+
#: wpbe.php:416
|
178 |
+
msgid "<strong>%blog_name%</strong> : will be replaced with your blog name."
|
179 |
+
msgstr "<strong>%blog_name%</strong> : Ihr Blog-Namen wird eingefügt."
|
180 |
+
|
181 |
+
#: wpbe.php:417
|
182 |
+
msgid "<strong>%blog_description%</strong> : will be replaced with your blog description."
|
183 |
+
msgstr "<strong>%blog_description%</strong> : Ihr Blog wird eingefügt."
|
184 |
+
|
185 |
+
#: wpbe.php:418
|
186 |
+
msgid "<strong>%admin_email%</strong> : will be replaced with admin email."
|
187 |
+
msgstr "<strong>%admin_email%</strong> : die Administrator-E-Mail wird eingefügt."
|
188 |
+
|
189 |
+
#: wpbe.php:419
|
190 |
+
msgid "<strong>%date%</strong> : will be replaced with current date, as formatted in <a href=\"options-general.php\">general options</a>."
|
191 |
+
msgstr "<strong>%date%</strong> : das aktuelle Datum wird eingefügt, in der Form <a href=\"options-general.php\">general options</a>."
|
192 |
+
|
193 |
+
#: wpbe.php:420
|
194 |
+
msgid "<strong>%time%</strong> : will be replaced with current time, as formatted in <a href=\"options-general.php\">general options</a>."
|
195 |
+
msgstr "<strong>%time%</strong> : die aktuelle Zeit wird eingefügt, in der Form <a href=\"options-general.php\">general options</a>."
|
196 |
+
|
langs/wp-better-emails-fr_FR.mo
CHANGED
Binary file
|
langs/wp-better-emails-fr_FR.po
CHANGED
@@ -1,236 +1,196 @@
|
|
1 |
-
#
|
2 |
-
# Copyright (C) 2010
|
3 |
# This file is distributed under the same license as the package.
|
4 |
-
# FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
|
5 |
-
#
|
6 |
msgid ""
|
7 |
msgstr ""
|
8 |
"Project-Id-Version: WP Better Emails\n"
|
9 |
"Report-Msgid-Bugs-To: http://wordpress.org/tag/wp-better-emails\n"
|
10 |
-
"POT-Creation-Date:
|
11 |
-
"PO-Revision-Date: 2010-11-29 19:45+0100\n"
|
12 |
-
"Last-Translator: Nicolas Lemoine <nico@yamoy.org>\n"
|
13 |
-
"Language-Team: ArtyShow <plugins@artyshow-studio.fr>\n"
|
14 |
"MIME-Version: 1.0\n"
|
15 |
-
"Content-Type: text/plain; charset=
|
16 |
"Content-Transfer-Encoding: 8bit\n"
|
|
|
|
|
|
|
17 |
"X-Poedit-Language: French\n"
|
18 |
-
"X-Poedit-Country: FRANCE\n"
|
19 |
-
|
20 |
-
#: email_template.php:33
|
21 |
-
msgid "Powered by Wordpress"
|
22 |
-
msgstr "Propulsé par Wordpress"
|
23 |
-
|
24 |
-
#: email_template.php:34
|
25 |
-
msgid "Date"
|
26 |
-
msgstr "Date"
|
27 |
-
|
28 |
-
#: email_template.php:34
|
29 |
-
msgid "Email sent the"
|
30 |
-
msgstr "Email envoyé le"
|
31 |
-
|
32 |
-
#: email_template.php:35
|
33 |
-
msgid "Contact"
|
34 |
-
msgstr "Contact"
|
35 |
-
|
36 |
-
#: email_template.php:35
|
37 |
-
msgid "For any request, please contact"
|
38 |
-
msgstr "Pour toute demande, contactez"
|
39 |
|
40 |
#: wpbe-options.php:2
|
41 |
-
|
42 |
-
|
|
|
43 |
|
44 |
#: wpbe-options.php:9
|
45 |
-
msgid "
|
46 |
-
msgstr "
|
47 |
-
|
48 |
-
#: wpbe-options.php:10
|
49 |
-
msgid "Template options"
|
50 |
-
msgstr "Options du modèle"
|
51 |
-
|
52 |
-
#: wpbe-options.php:11
|
53 |
-
msgid "Help & support"
|
54 |
-
msgstr "Aide & support"
|
55 |
-
|
56 |
-
#: wpbe-options.php:14
|
57 |
-
msgid "Change the Wordpress default behavior when sending emails to users (i.e. comment notifications, lost password, etc.), set your own sender name and email address."
|
58 |
-
msgstr "Modifiez le comportement par défaut de Wordpress lors de l'envoi d'emails aux utilisateurs (notifications, mot de passe perdu, etc.), configurez votre propre nom d'envoyeur et adresse email d'envoyeur."
|
59 |
-
|
60 |
-
#: wpbe-options.php:17
|
61 |
-
msgid "From name"
|
62 |
-
msgstr "Nom"
|
63 |
|
64 |
-
#: wpbe-options.php:
|
65 |
-
|
66 |
-
|
67 |
-
msgstr "requis"
|
68 |
|
69 |
-
#: wpbe-options.php:
|
70 |
-
msgid "
|
71 |
msgstr "Adresse email"
|
72 |
|
73 |
-
#: wpbe-options.php:
|
74 |
-
msgid "Template
|
75 |
-
msgstr "
|
76 |
|
77 |
-
#: wpbe-options.php:
|
78 |
-
msgid "
|
79 |
-
msgstr "
|
80 |
|
81 |
-
#: wpbe-options.php:
|
82 |
-
msgid "
|
83 |
-
msgstr "
|
84 |
|
85 |
-
#: wpbe-options.php:
|
86 |
-
msgid "
|
87 |
-
msgstr "
|
88 |
|
89 |
#: wpbe-options.php:35
|
90 |
-
msgid "<strong>%blog_url%</strong> : will be replaced by your blog URL."
|
91 |
-
msgstr "<strong>%blog_url%</strong> : sera remplacé par l'URL de votre blog."
|
92 |
-
|
93 |
-
#: wpbe-options.php:36
|
94 |
-
msgid "<strong>%blog_name%</strong> : will be replaced by your blog name."
|
95 |
-
msgstr "<strong>%blog_name%</strong> : sera remplacé par le nom de votre blog."
|
96 |
-
|
97 |
-
#: wpbe-options.php:37
|
98 |
-
msgid "<strong>%blog_description%</strong> : will be replaced by your blog description."
|
99 |
-
msgstr "<strong>%blog_description%</strong> : will be replaced by your blog description."
|
100 |
-
|
101 |
-
#: wpbe-options.php:38
|
102 |
-
msgid "<strong>%admin_email%</strong> : will be replaced by admin email."
|
103 |
-
msgstr "<strong>%admin_email%</strong> : sera remplacé par l'email de l'admin."
|
104 |
-
|
105 |
-
#: wpbe-options.php:39
|
106 |
-
msgid "<strong>%date%</strong> : will be replaced by current date, as formatted in <a href=\"options-general.php\">general options</a>."
|
107 |
-
msgstr "<strong>%date%</strong> : sera remplacé par la date courante, formatée telle que spécifié dans les <a href=\"options-general.php\">options générales</a>."
|
108 |
-
|
109 |
-
#: wpbe-options.php:40
|
110 |
-
msgid "<strong>%time%</strong> : will be replaced by current time, as formatted in <a href=\"options-general.php\">general options</a>."
|
111 |
-
msgstr "<strong>%time%</strong> : sera remplacé par l'heure courante, formatée telle que spécifié dans les <a href=\"options-general.php\">options générales</a>."
|
112 |
-
|
113 |
-
#: wpbe-options.php:46
|
114 |
-
msgid "HTML Template"
|
115 |
-
msgstr "Modèle HTML"
|
116 |
-
|
117 |
-
#: wpbe-options.php:51
|
118 |
msgid "Send an email preview to"
|
119 |
msgstr "Envoyer un aperçu à"
|
120 |
|
121 |
-
#: wpbe-options.php:
|
122 |
msgid "Send"
|
123 |
msgstr "Envoyer"
|
124 |
|
125 |
-
#: wpbe-options.php:
|
126 |
msgid "You must save your template before sending an email preview."
|
127 |
-
msgstr "Vous devez enregistrer
|
128 |
-
|
129 |
-
#: wpbe-options.php:64
|
130 |
-
msgid "Designing & coding email templates"
|
131 |
-
msgstr "Concevoir & coder des modèles d'emails"
|
132 |
-
|
133 |
-
#: wpbe-options.php:65
|
134 |
-
msgid "Here are a few ressources about email formatting :"
|
135 |
-
msgstr "Voici quelques ressources à propos du codage pour email :"
|
136 |
|
137 |
-
#: wpbe-options.php:
|
138 |
-
msgid "
|
139 |
-
msgstr ""
|
140 |
-
|
141 |
-
#: wpbe-options.php:68
|
142 |
-
msgid "<a href=\"http://articles.sitepoint.com/article/code-html-email-newsletters/\" target=\"_blank\">http://articles.sitepoint.com/article/code-html-email-newsletters/</a>"
|
143 |
-
msgstr ""
|
144 |
-
|
145 |
-
#: wpbe-options.php:70
|
146 |
-
msgid "Converting HTML templates"
|
147 |
-
msgstr "Convertir des modèles HTML"
|
148 |
-
|
149 |
-
#: wpbe-options.php:71
|
150 |
-
msgid "Coding HTML for emails requires CSS styles to be inline. Here's a tool powered by MailChimp that will convert your styles placed in the <code><head></code> tag to inline : "
|
151 |
-
msgstr "Coder du HTML pour les emails requiert que les styles CSS soient intégrés \"inline\". Voici un outil proposé par MailChimp qui convertit les styles placés dans la balise <code><head></code> en styles \"inline\" :"
|
152 |
-
|
153 |
-
#: wpbe-options.php:73
|
154 |
-
msgid "<a href=\"http://www.mailchimp.com/labs/inlinecss.php\" target=\"_blank\">http://www.mailchimp.com/labs/inlinecss.php</a>"
|
155 |
-
msgstr ""
|
156 |
|
157 |
-
#: wpbe-options.php:
|
158 |
-
msgid "
|
159 |
-
msgstr "
|
160 |
|
161 |
-
#: wpbe-options.php:
|
162 |
msgid "If you have any idea to improve this plugin or any bug to report, please email me at : <a href=\"mailto:plugins@artyshow-studio.fr?subject=[wp-better-emails]\">plugins@artyshow-studio.fr</a>"
|
163 |
msgstr "Si vous avez des idées d'amélioration ou des bugs à mentionner, envoyez-moi un email à <a href=\"mailto:plugins@artyshow-studio.fr?subject=[wp-better-emails]\">plugins@artyshow-studio.fr</a>"
|
164 |
|
165 |
-
#: wpbe-options.php:
|
166 |
-
msgid "
|
167 |
-
msgstr "
|
168 |
|
169 |
-
#:
|
170 |
-
msgid "
|
171 |
-
msgstr "
|
172 |
|
173 |
-
#:
|
174 |
-
msgid "
|
175 |
-
msgstr "
|
176 |
|
177 |
-
#:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
msgid "Settings"
|
179 |
msgstr "Configuration"
|
180 |
|
181 |
-
#: wpbe.php:
|
182 |
msgid "WP Better Emails requires WordPress 2.8 or newer."
|
183 |
-
msgstr "WP Better Emails requiert Wordpress 2.8 ou
|
|
|
|
|
|
|
|
|
184 |
|
185 |
-
#: wpbe.php:
|
186 |
-
msgid "
|
187 |
-
msgstr "
|
188 |
|
189 |
-
#: wpbe.php:
|
190 |
msgid "Please enter a valid sender email address."
|
191 |
msgstr "Veuillez entrer une adresse email valide pour l'envoyeur."
|
192 |
|
193 |
-
#: wpbe.php:
|
194 |
msgid "Template is empty"
|
195 |
msgstr "Le modèle est vide"
|
196 |
|
197 |
-
#: wpbe.php:
|
198 |
-
msgid "No content tag found.
|
199 |
msgstr "Aucun tag de contenu n'a été trouvé. Veuillez insérer le tag %content% dans votre template."
|
200 |
|
201 |
-
#: wpbe.php:
|
202 |
msgid "Please enter an email"
|
203 |
msgstr "Veuillez entrer un email"
|
204 |
|
205 |
-
#: wpbe.php:
|
206 |
msgid "Please enter a valid email"
|
207 |
msgstr "Veuillez entrer un email valide"
|
208 |
|
209 |
-
#: wpbe.php:
|
210 |
msgid "Hey !"
|
211 |
msgstr "Hey !"
|
212 |
|
213 |
-
#: wpbe.php:
|
214 |
-
msgid "This is a sample email to test your template."
|
215 |
msgstr "Ceci un email factice pour tester votre modèle."
|
216 |
|
217 |
-
#: wpbe.php:
|
218 |
-
msgid "If you're not skilled in HTML/CSS email coding, I strongly recommend to leave the default template as it is. It has been tested on various and popular email clients like Gmail, Yahoo Mail, Hotmail/Live, Thunderbird, Apple Mail, Outlook, and many more.
|
219 |
msgstr "Si vous n'êtes pas compétent en intégraiton HTML/CSS, je vous recommande vivement de laisser le modèle tel qu'il est. Il a été testé sur de nombreux et populaires clients mail comme Gmail, Yahoo Mail, Hotmail/Live, Thunderbird, Apple Mail, Outlook, et bien plus encore."
|
220 |
|
221 |
-
#: wpbe.php:
|
222 |
-
msgid "If you have any
|
223 |
-
msgstr "Si vous
|
224 |
|
225 |
-
#: wpbe.php:
|
226 |
msgid "Email template preview"
|
227 |
msgstr "Aperçu du modèle d'email"
|
228 |
|
229 |
-
#: wpbe.php:
|
230 |
-
msgid "An email preview has been successfully sent to "
|
231 |
-
msgstr "Un email d'aperçu
|
232 |
|
233 |
-
#: wpbe.php:
|
234 |
msgid "An error occured while sending email. Please check your server configuration."
|
235 |
msgstr "Une erreur a eu lieu lors de l'envoi. Vérifiez la configuration de votre serveur."
|
236 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Copyright (C) 2010
|
|
|
2 |
# This file is distributed under the same license as the package.
|
|
|
|
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
"Project-Id-Version: WP Better Emails\n"
|
6 |
"Report-Msgid-Bugs-To: http://wordpress.org/tag/wp-better-emails\n"
|
7 |
+
"POT-Creation-Date: 2011-09-06 23:22:41+00:00\n"
|
|
|
|
|
|
|
8 |
"MIME-Version: 1.0\n"
|
9 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
11 |
+
"PO-Revision-Date: 2011-09-12 17:26+0100\n"
|
12 |
+
"Last-Translator: \n"
|
13 |
+
"Language-Team: Nicolas Lemoine <plugins@artyshow-studio.fr>\n"
|
14 |
"X-Poedit-Language: French\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
#: wpbe-options.php:2
|
17 |
+
#: wpbe.php:158
|
18 |
+
msgid "Email settings"
|
19 |
+
msgstr "Configuration des emails"
|
20 |
|
21 |
#: wpbe-options.php:9
|
22 |
+
msgid "Set your own sender name and email address. Default Wordpress values will be used if empty."
|
23 |
+
msgstr "Définissez votre propre nom d'envoyeur et adresse email d'envoyeur. Les valeurs par défaut de Wordpress seront utilisées si les champs sont laissés vides."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
|
25 |
+
#: wpbe-options.php:12
|
26 |
+
msgid "Name"
|
27 |
+
msgstr " Nom"
|
|
|
28 |
|
29 |
+
#: wpbe-options.php:16
|
30 |
+
msgid "Email address"
|
31 |
msgstr "Adresse email"
|
32 |
|
33 |
+
#: wpbe-options.php:22
|
34 |
+
msgid "HTML Template"
|
35 |
+
msgstr "Modèle HTML"
|
36 |
|
37 |
+
#: wpbe-options.php:24
|
38 |
+
msgid "Live template preview"
|
39 |
+
msgstr "Aperçu rapide du modèle"
|
40 |
|
41 |
+
#: wpbe-options.php:24
|
42 |
+
msgid "Live preview"
|
43 |
+
msgstr "Aperçu"
|
44 |
|
45 |
+
#: wpbe-options.php:26
|
46 |
+
msgid "Edit the HTML email template if you want to customize it. You might have a look at the <a href=\"#\" id=\"wpbe_help\">help tab</a> for further information."
|
47 |
+
msgstr "Editer le modèle HTML si vous souhaitez le personnaliser. <a href=\"#\" id=\"wpbe_help\">Consultez l'aide</a> pour plus d'information."
|
48 |
|
49 |
#: wpbe-options.php:35
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
msgid "Send an email preview to"
|
51 |
msgstr "Envoyer un aperçu à"
|
52 |
|
53 |
+
#: wpbe-options.php:39
|
54 |
msgid "Send"
|
55 |
msgstr "Envoyer"
|
56 |
|
57 |
+
#: wpbe-options.php:41
|
58 |
msgid "You must save your template before sending an email preview."
|
59 |
+
msgstr "Vous devez enregistrer le modèle avant d'envoyer un aperçu."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
|
61 |
+
#: wpbe-options.php:46
|
62 |
+
msgid "Save Changes"
|
63 |
+
msgstr "Enregistrer les modifications"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
|
65 |
+
#: wpbe-options.php:52
|
66 |
+
msgid "Support & bug report"
|
67 |
+
msgstr "Support & report de bugs"
|
68 |
|
69 |
+
#: wpbe-options.php:53
|
70 |
msgid "If you have any idea to improve this plugin or any bug to report, please email me at : <a href=\"mailto:plugins@artyshow-studio.fr?subject=[wp-better-emails]\">plugins@artyshow-studio.fr</a>"
|
71 |
msgstr "Si vous avez des idées d'amélioration ou des bugs à mentionner, envoyez-moi un email à <a href=\"mailto:plugins@artyshow-studio.fr?subject=[wp-better-emails]\">plugins@artyshow-studio.fr</a>"
|
72 |
|
73 |
+
#: wpbe-options.php:55
|
74 |
+
msgid "You like this plugin ? You use it in a business context ? Please, consider a <a href=\"%s\" target=\"_blank\" rel=\"external\">donation</a>."
|
75 |
+
msgstr "Vous aimez ce plugin ? Vous l'utilisez dans un contexte professionnel ? Considérez un <a href=\"%s\" target=\"_blank\" rel=\"external\">don</a>."
|
76 |
|
77 |
+
#: templates/template-1.php:33
|
78 |
+
msgid "Date"
|
79 |
+
msgstr "Date"
|
80 |
|
81 |
+
#: templates/template-1.php:33
|
82 |
+
msgid "Email sent"
|
83 |
+
msgstr "Email envoyé le"
|
84 |
|
85 |
+
#: templates/template-1.php:34
|
86 |
+
msgid "Contact"
|
87 |
+
msgstr "Contact"
|
88 |
+
|
89 |
+
#: templates/template-1.php:34
|
90 |
+
msgid "For any requests, please contact"
|
91 |
+
msgstr "Pour toute demande, contactez"
|
92 |
+
|
93 |
+
#: wpbe.php:131
|
94 |
msgid "Settings"
|
95 |
msgstr "Configuration"
|
96 |
|
97 |
+
#: wpbe.php:147
|
98 |
msgid "WP Better Emails requires WordPress 2.8 or newer."
|
99 |
+
msgstr "WP Better Emails requiert Wordpress 2.8 ou une version plus récente."
|
100 |
+
|
101 |
+
#: wpbe.php:147
|
102 |
+
msgid "Upgrade your Wordpress installation."
|
103 |
+
msgstr "Mettez à jour votre installation de Wordpress."
|
104 |
|
105 |
+
#: wpbe.php:158
|
106 |
+
msgid "WP Better Emails"
|
107 |
+
msgstr "WP Better Emails"
|
108 |
|
109 |
+
#: wpbe.php:228
|
110 |
msgid "Please enter a valid sender email address."
|
111 |
msgstr "Veuillez entrer une adresse email valide pour l'envoyeur."
|
112 |
|
113 |
+
#: wpbe.php:238
|
114 |
msgid "Template is empty"
|
115 |
msgstr "Le modèle est vide"
|
116 |
|
117 |
+
#: wpbe.php:241
|
118 |
+
msgid "No content tag found. The %content% tag is required in your template"
|
119 |
msgstr "Aucun tag de contenu n'a été trouvé. Veuillez insérer le tag %content% dans votre template."
|
120 |
|
121 |
+
#: wpbe.php:259
|
122 |
msgid "Please enter an email"
|
123 |
msgstr "Veuillez entrer un email"
|
124 |
|
125 |
+
#: wpbe.php:261
|
126 |
msgid "Please enter a valid email"
|
127 |
msgstr "Veuillez entrer un email valide"
|
128 |
|
129 |
+
#: wpbe.php:262
|
130 |
msgid "Hey !"
|
131 |
msgstr "Hey !"
|
132 |
|
133 |
+
#: wpbe.php:264
|
134 |
+
msgid "This is a sample email to test your HTML template."
|
135 |
msgstr "Ceci un email factice pour tester votre modèle."
|
136 |
|
137 |
+
#: wpbe.php:266
|
138 |
+
msgid "If you're not skilled in HTML/CSS email coding, I strongly recommend to leave the default template as it is. It has been tested on various and popular email clients like Gmail, Yahoo Mail, Hotmail/Live, Thunderbird, Apple Mail, Outlook, and many more."
|
139 |
msgstr "Si vous n'êtes pas compétent en intégraiton HTML/CSS, je vous recommande vivement de laisser le modèle tel qu'il est. Il a été testé sur de nombreux et populaires clients mail comme Gmail, Yahoo Mail, Hotmail/Live, Thunderbird, Apple Mail, Outlook, et bien plus encore."
|
140 |
|
141 |
+
#: wpbe.php:268
|
142 |
+
msgid "If you have any problems or any suggestions to improve this plugin, please let me know."
|
143 |
+
msgstr "Si vous recontrez un problèmes ou des suggestions d'améliorations, n'hésitez pas à m'en faire part."
|
144 |
|
145 |
+
#: wpbe.php:269
|
146 |
msgid "Email template preview"
|
147 |
msgstr "Aperçu du modèle d'email"
|
148 |
|
149 |
+
#: wpbe.php:270
|
150 |
+
msgid "An email preview has been successfully sent to %s"
|
151 |
+
msgstr "Un email d'aperçu vient d'être envoyé avec succès à %s"
|
152 |
|
153 |
+
#: wpbe.php:273
|
154 |
msgid "An error occured while sending email. Please check your server configuration."
|
155 |
msgstr "Une erreur a eu lieu lors de l'envoi. Vérifiez la configuration de votre serveur."
|
156 |
|
157 |
+
#: wpbe.php:410
|
158 |
+
msgid "Some dynamic tags can be included in your email template :"
|
159 |
+
msgstr "Des tags dynamiques peuvent être inclus dans votre template :"
|
160 |
+
|
161 |
+
#: wpbe.php:412
|
162 |
+
msgid "<strong>%content%</strong> : will be replaced with the message content."
|
163 |
+
msgstr "<strong>%content%</strong> : sera remplacé par le contenu du message."
|
164 |
+
|
165 |
+
#: wpbe.php:413
|
166 |
+
msgid "NOTE: The content tag is <strong>required</strong>, WP Better Emails will be automatically desactivated if no content tag is found."
|
167 |
+
msgstr "NOTE: Le tag \"content\" est <strong>requis</strong>, WP Better Emails sera automatiquement désactivé si ce tag n'est pas trouvé dans le modèle."
|
168 |
+
|
169 |
+
#: wpbe.php:414
|
170 |
+
msgid "<strong>%blog_url%</strong> : will be replaced with your blog URL."
|
171 |
+
msgstr "<strong>%blog_url%</strong> : sera remplacé par l'URL de votre blog."
|
172 |
+
|
173 |
+
#: wpbe.php:415
|
174 |
+
msgid "<strong>%home_url%</strong> : will be replaced with your home URL."
|
175 |
+
msgstr "<strong>%home_url%</strong> : sera remplacé par l'URL d'accueil de votre blog."
|
176 |
+
|
177 |
+
#: wpbe.php:416
|
178 |
+
msgid "<strong>%blog_name%</strong> : will be replaced with your blog name."
|
179 |
+
msgstr "<strong>%blog_name%</strong> : sera remplacé par le nom de votre blog."
|
180 |
+
|
181 |
+
#: wpbe.php:417
|
182 |
+
msgid "<strong>%blog_description%</strong> : will be replaced with your blog description."
|
183 |
+
msgstr "<strong>%blog_description%</strong> : sera remplacé par la description de votre blog."
|
184 |
+
|
185 |
+
#: wpbe.php:418
|
186 |
+
msgid "<strong>%admin_email%</strong> : will be replaced with admin email."
|
187 |
+
msgstr "<strong>%admin_email%</strong> : sera remplacé par l'email de l'administrateur."
|
188 |
+
|
189 |
+
#: wpbe.php:419
|
190 |
+
msgid "<strong>%date%</strong> : will be replaced with current date, as formatted in <a href=\"options-general.php\">general options</a>."
|
191 |
+
msgstr "<strong>%date%</strong> : sera remplacé par la date courante, telle que formatée dans les <a href=\"options-general.php\">options générales</a>."
|
192 |
+
|
193 |
+
#: wpbe.php:420
|
194 |
+
msgid "<strong>%time%</strong> : will be replaced with current time, as formatted in <a href=\"options-general.php\">general options</a>."
|
195 |
+
msgstr "<strong>%time%</strong> : sera remplacé par l'heure courante, telle que formatée dans les <a href=\"options-general.php\">options générales</a>."
|
196 |
+
|
langs/wp-better-emails-he_IL.mo
ADDED
Binary file
|
langs/wp-better-emails-he_IL.po
ADDED
@@ -0,0 +1,197 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Copyright (C) 2010
|
2 |
+
# This file is distributed under the same license as the package.
|
3 |
+
msgid ""
|
4 |
+
msgstr ""
|
5 |
+
"Project-Id-Version: WP-Better-Emails\n"
|
6 |
+
"Report-Msgid-Bugs-To: http://wordpress.org/tag/wp-better-emails\n"
|
7 |
+
"POT-Creation-Date: 2011-09-06 23:22:41+00:00\n"
|
8 |
+
"MIME-Version: 1.0\n"
|
9 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
10 |
+
"Content-Transfer-Encoding: 8bit\n"
|
11 |
+
"PO-Revision-Date: 2011-09-12 17:26+0100\n"
|
12 |
+
"Last-Translator: \n"
|
13 |
+
"Language-Team: Avi Ben-Avraham <avi@nrich.co.il>\n"
|
14 |
+
"X-Poedit-Language: Hebrew\n"
|
15 |
+
"X-Poedit-Country: ISRAEL\n"
|
16 |
+
|
17 |
+
#: wpbe-options.php:2
|
18 |
+
#: wpbe.php:158
|
19 |
+
msgid "Email settings"
|
20 |
+
msgstr "הגדרות מייל"
|
21 |
+
|
22 |
+
#: wpbe-options.php:9
|
23 |
+
msgid "Set your own sender name and email address. Default Wordpress values will be used if empty."
|
24 |
+
msgstr "קבע בעצמך את שם השולח וכתובת המייל. אם תשאיר שדות אלה ריקים ייעשה שימוש בערכי ברירת המחדל של וורדפרס."
|
25 |
+
|
26 |
+
#: wpbe-options.php:12
|
27 |
+
msgid "Name"
|
28 |
+
msgstr "שם השולח"
|
29 |
+
|
30 |
+
#: wpbe-options.php:16
|
31 |
+
msgid "Email address"
|
32 |
+
msgstr "כתובת המייל של השולח"
|
33 |
+
|
34 |
+
#: wpbe-options.php:22
|
35 |
+
msgid "HTML Template"
|
36 |
+
msgstr "HTML תבנית"
|
37 |
+
|
38 |
+
#: wpbe-options.php:24
|
39 |
+
msgid "Live template preview"
|
40 |
+
msgstr "תצוגה מוקדמת אמיתית של התבנית"
|
41 |
+
|
42 |
+
#: wpbe-options.php:24
|
43 |
+
msgid "Live preview"
|
44 |
+
msgstr "לחיות תצוגה מקדימה"
|
45 |
+
|
46 |
+
#: wpbe-options.php:26
|
47 |
+
msgid "Edit the HTML email template if you want to customize it. You might have a look at <a href=\"#\" id=\"wpbe_help\">help tab</a> for further information."
|
48 |
+
msgstr ""
|
49 |
+
|
50 |
+
#: wpbe-options.php:35
|
51 |
+
msgid "Send an email preview to"
|
52 |
+
msgstr "שלח תצוגה מקדימה במייל ל"
|
53 |
+
|
54 |
+
#: wpbe-options.php:39
|
55 |
+
msgid "Send"
|
56 |
+
msgstr "שלח"
|
57 |
+
|
58 |
+
#: wpbe-options.php:41
|
59 |
+
msgid "You must save your template before sending an email preview."
|
60 |
+
msgstr "הינך חייב לשמור את התבנית לפני שליחה תצוגה מוקדמת של מייל"
|
61 |
+
|
62 |
+
#: wpbe-options.php:46
|
63 |
+
msgid "Save Changes"
|
64 |
+
msgstr "שמור שינויים"
|
65 |
+
|
66 |
+
#: wpbe-options.php:52
|
67 |
+
msgid "Support & bug report"
|
68 |
+
msgstr "תמיכה ודיווח על בעיות"
|
69 |
+
|
70 |
+
#: wpbe-options.php:53
|
71 |
+
msgid "If you have any idea to improve this plugin or any bug to report, please email me at : <a href=\"mailto:plugins@artyshow-studio.fr?subject=[wp-better-emails]\">plugins@artyshow-studio.fr</a>"
|
72 |
+
msgstr "אם יש לך רעיון כיצד לשפר את התוסף או אם מצאת באג, שלח לי מייל ל: <a href=\"mailto:plugins@artyshow-studio.fr?subject=[wp-better-emails]\">plugins@artyshow-studio.fr</a>"
|
73 |
+
|
74 |
+
#: wpbe-options.php:55
|
75 |
+
msgid "You like this plugin ? You use it in a business context ? Please, consider a <a href=\"%s\" target=\"_blank\" rel=\"external\">donation</a>."
|
76 |
+
msgstr "אהבת את התוסף? משתמש בתוסף לצרכים עסקיים? אנא שקול <a href=\"%s\" target=\"_blank\" rel=\"external\">לתרום</a>."
|
77 |
+
|
78 |
+
#: templates/template-1.php:33
|
79 |
+
msgid "Date"
|
80 |
+
msgstr "תאריך"
|
81 |
+
|
82 |
+
#: templates/template-1.php:33
|
83 |
+
msgid "Email sent"
|
84 |
+
msgstr "נשלח במייל"
|
85 |
+
|
86 |
+
#: templates/template-1.php:34
|
87 |
+
msgid "Contact"
|
88 |
+
msgstr "צור קשר"
|
89 |
+
|
90 |
+
#: templates/template-1.php:34
|
91 |
+
msgid "For any requests, please contact"
|
92 |
+
msgstr "בכל בקשה, אנא צור קשר"
|
93 |
+
|
94 |
+
#: wpbe.php:131
|
95 |
+
msgid "Settings"
|
96 |
+
msgstr "הגדרות"
|
97 |
+
|
98 |
+
#: wpbe.php:147
|
99 |
+
msgid "WP Better Emails requires WordPress 2.8 or newer."
|
100 |
+
msgstr "WP Better Emails עובד רק על וורדפרס 2.8 ומעלה"
|
101 |
+
|
102 |
+
#: wpbe.php:147
|
103 |
+
msgid "Upgrade your Wordpress installation."
|
104 |
+
msgstr "שדרג את התקנת הוורדפרס שברשותך"
|
105 |
+
|
106 |
+
#: wpbe.php:158
|
107 |
+
msgid "WP Better Emails"
|
108 |
+
msgstr "WP Better Emails"
|
109 |
+
|
110 |
+
#: wpbe.php:228
|
111 |
+
msgid "Please enter a valid sender email address."
|
112 |
+
msgstr "אנא הזן כתובת מייל חוקית של השולח"
|
113 |
+
|
114 |
+
#: wpbe.php:238
|
115 |
+
msgid "Template is empty"
|
116 |
+
msgstr "התבנית ריקה"
|
117 |
+
|
118 |
+
#: wpbe.php:241
|
119 |
+
msgid "No content tag found. The %content% tag is required in your template"
|
120 |
+
msgstr "לא נמצאו תגיות תוכן. התגית %content% נדרשת בתבנית שלך"
|
121 |
+
|
122 |
+
#: wpbe.php:259
|
123 |
+
msgid "Please enter an email"
|
124 |
+
msgstr "אנא הזן דואר אלקטרוני"
|
125 |
+
|
126 |
+
#: wpbe.php:261
|
127 |
+
msgid "Please enter a valid email"
|
128 |
+
msgstr "אנא הזן כתובת דואר אלקטרוני חוקית"
|
129 |
+
|
130 |
+
#: wpbe.php:262
|
131 |
+
msgid "Hey !"
|
132 |
+
msgstr "היי!"
|
133 |
+
|
134 |
+
#: wpbe.php:264
|
135 |
+
msgid "This is a sample email to test your HTML template."
|
136 |
+
msgstr "זהו מייל לדוגמה לבחינת תבנית ה- HTML שיצרת"
|
137 |
+
|
138 |
+
#: wpbe.php:266
|
139 |
+
msgid "If you're not skilled in HTML/CSS email coding, I strongly recommend to leave the default template as it is. It has been tested on various and popular email clients like Gmail, Yahoo Mail, Hotmail/Live, Thunderbird, Apple Mail, Outlook, and many more."
|
140 |
+
msgstr "אם אין לך ניסיון בכתיבת HTML/CSS, אני ממליץ בחום להשאיר את תבנית ברירת המחדל כמו שהיא. התבנית נבחנה בהצלחה על מגוון תוכנות וממשקי מייל כמו ג'ימייל, Yahoo Mail, Hotmail/Live, Thunderbird, Apple Mail, Outlook ועוד רבים אחרים."
|
141 |
+
|
142 |
+
#: wpbe.php:268
|
143 |
+
msgid "If you have any problems or any suggestions to improve this plugin, please let me know."
|
144 |
+
msgstr "אם הינך נתקל בכל בעיה או יש לך הצעות לשיפור, אנא הודע לי"
|
145 |
+
|
146 |
+
#: wpbe.php:269
|
147 |
+
msgid "Email template preview"
|
148 |
+
msgstr "תצוגה מוקדמת של תבנית המייל"
|
149 |
+
|
150 |
+
#: wpbe.php:270
|
151 |
+
msgid "An email preview has been successfully sent to %s"
|
152 |
+
msgstr "An email preview has been successfully sent to %s"
|
153 |
+
|
154 |
+
#: wpbe.php:273
|
155 |
+
msgid "An error occured while sending email. Please check your server configuration."
|
156 |
+
msgstr "שגיאה ארעה בזמן שליחת המייל. אנא בדוק את הגדרות השרת שלך"
|
157 |
+
|
158 |
+
#: wpbe.php:410
|
159 |
+
msgid "Some dynamic tags can be included in your email template :"
|
160 |
+
msgstr "ניתן לכלול מספר תגיות דינמיות בתבנית המייל שלך"
|
161 |
+
|
162 |
+
#: wpbe.php:412
|
163 |
+
msgid "<strong>%content%</strong> : will be replaced with the message content."
|
164 |
+
msgstr "<strong>%content%</strong>: יוחלף בתוכן ההודעה"
|
165 |
+
|
166 |
+
#: wpbe.php:413
|
167 |
+
msgid "NOTE: The content tag is <strong>required</strong>, WP Better Emails will be automatically desactivated if no content tag is found."
|
168 |
+
msgstr "שים לב: תגית התוכן היא <strong>required</strong>.WP Better Emails לא יופעל אם לא תימצא כל תגית תוכן."
|
169 |
+
|
170 |
+
#: wpbe.php:414
|
171 |
+
msgid "<strong>%blog_url%</strong> : will be replaced with your blog URL."
|
172 |
+
msgstr "<strong>%blog_url%</strong>: יוחלף בכתובת הבלוג שלך"
|
173 |
+
|
174 |
+
#: wpbe.php:415
|
175 |
+
msgid "<strong>%home_url%</strong> : will be replaced with your home URL."
|
176 |
+
msgstr "<strong>%home_url%</strong>: יוחלף בכתובת הבית שלך"
|
177 |
+
|
178 |
+
#: wpbe.php:416
|
179 |
+
msgid "<strong>%blog_name%</strong> : will be replaced with your blog name."
|
180 |
+
msgstr "<strong>%blog_name%</strong>: יוחלף בשם הבלוג שלך"
|
181 |
+
|
182 |
+
#: wpbe.php:417
|
183 |
+
msgid "<strong>%blog_description%</strong> : will be replaced with your blog description."
|
184 |
+
msgstr "<strong>%blog_description%</strong>: יוחלף בתיאור הבלוג שלך"
|
185 |
+
|
186 |
+
#: wpbe.php:418
|
187 |
+
msgid "<strong>%admin_email%</strong> : will be replaced with admin email."
|
188 |
+
msgstr "<strong>%admin_email%</strong>: יוחלף בכתובת המייל של המנהל"
|
189 |
+
|
190 |
+
#: wpbe.php:419
|
191 |
+
msgid "<strong>%date%</strong> : will be replaced with current date, as formatted in <a href=\"options-general.php\">general options</a>."
|
192 |
+
msgstr "<strong>%date%</strong>: יוחלף בתאריך הנוכחי כמוגדר ב- <a href=\"options-general.php\">אפשרויות כלליות</a>."
|
193 |
+
|
194 |
+
#: wpbe.php:420
|
195 |
+
msgid "<strong>%time%</strong> : will be replaced with current time, as formatted in <a href=\"options-general.php\">general options</a>."
|
196 |
+
msgstr "<strong>%time%</strong>: יוחלף בזמן הנוכחי, כמוגדר ב-<a href=\"options-general.php\">אפשרויות כלליות</a>."
|
197 |
+
|
langs/wp-better-emails-nl_NL.mo
DELETED
Binary file
|
langs/wp-better-emails-nl_NL.po
DELETED
@@ -1,236 +0,0 @@
|
|
1 |
-
# Translation of the WordPress plugin by .
|
2 |
-
# Copyright (C) 2010
|
3 |
-
# This file is distributed under the same license as the package.
|
4 |
-
# FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
|
5 |
-
#
|
6 |
-
msgid ""
|
7 |
-
msgstr ""
|
8 |
-
"Project-Id-Version: WP Better Emails\n"
|
9 |
-
"Report-Msgid-Bugs-To: http://wordpress.org/tag/wp-better-emails\n"
|
10 |
-
"POT-Creation-Date: 2010-11-29 15:16+0000\n"
|
11 |
-
"PO-Revision-Date: 2011-01-07 22:39+0100\n"
|
12 |
-
"Last-Translator: Glenn Mulleners <info@wp-expert.nl>\n"
|
13 |
-
"Language-Team: Glenn Mulleners <info@wp-expert.nl>\n"
|
14 |
-
"MIME-Version: 1.0\n"
|
15 |
-
"Content-Type: text/plain; charset=utf-8\n"
|
16 |
-
"Content-Transfer-Encoding: 8bit\n"
|
17 |
-
"X-Poedit-Language: Dutch\n"
|
18 |
-
"X-Poedit-Country: NETHERLANDS\n"
|
19 |
-
|
20 |
-
#: email_template.php:33
|
21 |
-
msgid "Powered by Wordpress"
|
22 |
-
msgstr "Powered by WordPress"
|
23 |
-
|
24 |
-
#: email_template.php:34
|
25 |
-
msgid "Date"
|
26 |
-
msgstr "Datum"
|
27 |
-
|
28 |
-
#: email_template.php:34
|
29 |
-
msgid "Email sent the"
|
30 |
-
msgstr "E-mail verstuurd"
|
31 |
-
|
32 |
-
#: email_template.php:35
|
33 |
-
msgid "Contact"
|
34 |
-
msgstr "Contact"
|
35 |
-
|
36 |
-
#: email_template.php:35
|
37 |
-
msgid "For any request, please contact"
|
38 |
-
msgstr "Voor eventuele vragen kun je contact opnemen met"
|
39 |
-
|
40 |
-
#: wpbe-options.php:2
|
41 |
-
msgid "Email options"
|
42 |
-
msgstr "E-mail opties"
|
43 |
-
|
44 |
-
#: wpbe-options.php:9
|
45 |
-
msgid "Sender options"
|
46 |
-
msgstr "Afzender opties"
|
47 |
-
|
48 |
-
#: wpbe-options.php:10
|
49 |
-
msgid "Template options"
|
50 |
-
msgstr "Sjabloon opties"
|
51 |
-
|
52 |
-
#: wpbe-options.php:11
|
53 |
-
msgid "Help & support"
|
54 |
-
msgstr "Hulp & ondersteuning"
|
55 |
-
|
56 |
-
#: wpbe-options.php:14
|
57 |
-
msgid "Change the Wordpress default behavior when sending emails to users (i.e. comment notifications, lost password, etc.), set your own sender name and email address."
|
58 |
-
msgstr "Wijzig het standaard gedrag van WordPress bij het verzenden van e-mails naar gebruikers (bijv. reactie notificaties, wachtwoord kwijt, etc), stel je eigen naam en e-mailadres in als afzender."
|
59 |
-
|
60 |
-
#: wpbe-options.php:17
|
61 |
-
msgid "From name"
|
62 |
-
msgstr "Afzender"
|
63 |
-
|
64 |
-
#: wpbe-options.php:17
|
65 |
-
#: wpbe-options.php:21
|
66 |
-
msgid "required"
|
67 |
-
msgstr "verplicht"
|
68 |
-
|
69 |
-
#: wpbe-options.php:21
|
70 |
-
msgid "From email address"
|
71 |
-
msgstr "Afzender e-mailadres"
|
72 |
-
|
73 |
-
#: wpbe-options.php:29
|
74 |
-
msgid "Template variables"
|
75 |
-
msgstr "Sjabloon variabelen"
|
76 |
-
|
77 |
-
#: wpbe-options.php:31
|
78 |
-
msgid "Some dynamic tags can be included in your email template :"
|
79 |
-
msgstr "Sommige dynamische tags kunnen worden opgenomen in je e-mail sjabloon:"
|
80 |
-
|
81 |
-
#: wpbe-options.php:33
|
82 |
-
msgid "<strong>%content%</strong> : will be replaced by the message content."
|
83 |
-
msgstr "<strong>%content%</strong> : zal worden vervangen door het bericht."
|
84 |
-
|
85 |
-
#: wpbe-options.php:34
|
86 |
-
msgid "NOTE: The content tag is <strong>required</strong>, WP Better Emails will be automatically desactivated if no content tag is found."
|
87 |
-
msgstr "LET OP: De inhoud tag is <strong>verplicht</strong>, WP Better Emails zal automatisch worden gedeactiveerd als de inhoud tag niet is gevonden."
|
88 |
-
|
89 |
-
#: wpbe-options.php:35
|
90 |
-
msgid "<strong>%blog_url%</strong> : will be replaced by your blog URL."
|
91 |
-
msgstr "<strong>%blog_url%</strong> : zal worden vervangen door de site URL."
|
92 |
-
|
93 |
-
#: wpbe-options.php:36
|
94 |
-
msgid "<strong>%blog_name%</strong> : will be replaced by your blog name."
|
95 |
-
msgstr "<strong>%blog_name%</strong> : zal worden vervangen door je site naam."
|
96 |
-
|
97 |
-
#: wpbe-options.php:37
|
98 |
-
msgid "<strong>%blog_description%</strong> : will be replaced by your blog description."
|
99 |
-
msgstr "<strong>%blog_description%</strong> : zal worden vervangen door je site beschrijving."
|
100 |
-
|
101 |
-
#: wpbe-options.php:38
|
102 |
-
msgid "<strong>%admin_email%</strong> : will be replaced by admin email."
|
103 |
-
msgstr "<strong>%admin_email%</strong> : zal worden vervangen door het e-mailadres van de beheerder."
|
104 |
-
|
105 |
-
#: wpbe-options.php:39
|
106 |
-
msgid "<strong>%date%</strong> : will be replaced by current date, as formatted in <a href=\"options-general.php\">general options</a>."
|
107 |
-
msgstr "<strong>%date%</strong> : zal worden vervangen door de huidige datum, zoals opgegeven in de <a href=\"options-general.php\">algemene instellingen</a>."
|
108 |
-
|
109 |
-
#: wpbe-options.php:40
|
110 |
-
msgid "<strong>%time%</strong> : will be replaced by current time, as formatted in <a href=\"options-general.php\">general options</a>."
|
111 |
-
msgstr "<strong>%date%</strong> : zal worden vervangen door de huidige tijd, zoals opgegeven in de <a href=\"options-general.php\">algemene instellingen</a>."
|
112 |
-
|
113 |
-
#: wpbe-options.php:46
|
114 |
-
msgid "HTML Template"
|
115 |
-
msgstr "HTML Sjabloon"
|
116 |
-
|
117 |
-
#: wpbe-options.php:51
|
118 |
-
msgid "Send an email preview to"
|
119 |
-
msgstr "Stuur e-mail voorbeeld naar"
|
120 |
-
|
121 |
-
#: wpbe-options.php:54
|
122 |
-
msgid "Send"
|
123 |
-
msgstr "Verstuur"
|
124 |
-
|
125 |
-
#: wpbe-options.php:56
|
126 |
-
msgid "You must save your template before sending an email preview."
|
127 |
-
msgstr "Je sjabloon moet worden opgeslagen voor het versturen van een e-mail voorbeeld."
|
128 |
-
|
129 |
-
#: wpbe-options.php:64
|
130 |
-
msgid "Designing & coding email templates"
|
131 |
-
msgstr "Ontwerpen en coderen van e-mail sjablonen"
|
132 |
-
|
133 |
-
#: wpbe-options.php:65
|
134 |
-
msgid "Here are a few ressources about email formatting :"
|
135 |
-
msgstr "Hier zijn een paar bronnen over e-mail opmaak:"
|
136 |
-
|
137 |
-
#: wpbe-options.php:67
|
138 |
-
msgid "<a href=\"http://www.campaignmonitor.com/resources/\" target=\"_blank\">http://www.campaignmonitor.com/resources/</a>"
|
139 |
-
msgstr "<a href=\"http://www.campaignmonitor.com/resources/\" target=\"_blank\">http://www.campaignmonitor.com/resources/</a>"
|
140 |
-
|
141 |
-
#: wpbe-options.php:68
|
142 |
-
msgid "<a href=\"http://articles.sitepoint.com/article/code-html-email-newsletters/\" target=\"_blank\">http://articles.sitepoint.com/article/code-html-email-newsletters/</a>"
|
143 |
-
msgstr "<a href=\"http://articles.sitepoint.com/article/code-html-email-newsletters/\" target=\"_blank\">http://articles.sitepoint.com/article/code-html-email-newsletters/</a>"
|
144 |
-
|
145 |
-
#: wpbe-options.php:70
|
146 |
-
msgid "Converting HTML templates"
|
147 |
-
msgstr "HTML sjabloon omzetten"
|
148 |
-
|
149 |
-
#: wpbe-options.php:71
|
150 |
-
msgid "Coding HTML for emails requires CSS styles to be inline. Here's a tool powered by MailChimp that will convert your styles placed in the <code><head></code> tag to inline : "
|
151 |
-
msgstr "Het coderen van HTML e-mails vereist inline CSS stijlen. Hier is een tool van MailChimp die je stijlen in de <code><head></code> tag naar inline stijlen omzet:"
|
152 |
-
|
153 |
-
#: wpbe-options.php:73
|
154 |
-
msgid "<a href=\"http://www.mailchimp.com/labs/inlinecss.php\" target=\"_blank\">http://www.mailchimp.com/labs/inlinecss.php</a>"
|
155 |
-
msgstr "<a href=\"http://www.mailchimp.com/labs/inlinecss.php\" target=\"_blank\">http://www.mailchimp.com/labs/inlinecss.php</a>"
|
156 |
-
|
157 |
-
#: wpbe-options.php:75
|
158 |
-
msgid "Requests & Bug report"
|
159 |
-
msgstr "Verzoeken & foutmeldingen"
|
160 |
-
|
161 |
-
#: wpbe-options.php:76
|
162 |
-
msgid "If you have any idea to improve this plugin or any bug to report, please email me at : <a href=\"mailto:plugins@artyshow-studio.fr?subject=[wp-better-emails]\">plugins@artyshow-studio.fr</a>"
|
163 |
-
msgstr "Als je een idee hebt om deze plugin te verbeteren of als je een fout wilt melden, stuur me een e-mail: <a href=\"mailto:plugins@artyshow-studio.fr?subject=[wp-better-emails]\">plugins@artyshow-studio.fr</a>"
|
164 |
-
|
165 |
-
#: wpbe-options.php:77
|
166 |
-
msgid "Credits"
|
167 |
-
msgstr "Dank aan"
|
168 |
-
|
169 |
-
#: wpbe-options.php:79
|
170 |
-
msgid "MarkItUp! : jQuery HTML editor <a href=\"http://markitup.jaysalvat.com/home/\" target=\"_blank\">http://markitup.jaysalvat.com/home/</a>"
|
171 |
-
msgstr "MarkItUp! : jQuery HTML editor <a href=\"http://markitup.jaysalvat.com/home/\" target=\"_blank\">http://markitup.jaysalvat.com/home/</a>"
|
172 |
-
|
173 |
-
#: wpbe-options.php:84
|
174 |
-
msgid "Save Changes"
|
175 |
-
msgstr "Wijzigingen opslaan"
|
176 |
-
|
177 |
-
#: wpbe.php:47
|
178 |
-
msgid "Settings"
|
179 |
-
msgstr "Instellingen"
|
180 |
-
|
181 |
-
#: wpbe.php:64
|
182 |
-
msgid "WP Better Emails requires WordPress 2.8 or newer."
|
183 |
-
msgstr "WP Better Emails vereist WordPress 2.8 of hoger."
|
184 |
-
|
185 |
-
#: wpbe.php:149
|
186 |
-
msgid "Please enter a sender email address."
|
187 |
-
msgstr "Vul een afzender e-mailadres in."
|
188 |
-
|
189 |
-
#: wpbe.php:152
|
190 |
-
msgid "Please enter a valid sender email address."
|
191 |
-
msgstr "Vul een geldig afzender e-mailadres in."
|
192 |
-
|
193 |
-
#: wpbe.php:162
|
194 |
-
msgid "Template is empty"
|
195 |
-
msgstr "Sjabloon ontbreekt."
|
196 |
-
|
197 |
-
#: wpbe.php:165
|
198 |
-
msgid "No content tag found. Please insert the %content% tag in your template"
|
199 |
-
msgstr "Geen inhoud tag gevonden. Plaats de %content% tag in je sjabloon"
|
200 |
-
|
201 |
-
#: wpbe.php:181
|
202 |
-
msgid "Please enter an email"
|
203 |
-
msgstr "Vul een e-mailadres in"
|
204 |
-
|
205 |
-
#: wpbe.php:183
|
206 |
-
msgid "Please enter a valid email"
|
207 |
-
msgstr "Vul een geldig e-mailadres in"
|
208 |
-
|
209 |
-
#: wpbe.php:184
|
210 |
-
msgid "Hey !"
|
211 |
-
msgstr "Hey!"
|
212 |
-
|
213 |
-
#: wpbe.php:186
|
214 |
-
msgid "This is a sample email to test your template."
|
215 |
-
msgstr "Dit is een voorbeeld e-mail om je sjabloon te testen."
|
216 |
-
|
217 |
-
#: wpbe.php:188
|
218 |
-
msgid "If you're not skilled in HTML/CSS email coding, I strongly recommend to leave the default template as it is. It has been tested on various and popular email clients like Gmail, Yahoo Mail, Hotmail/Live, Thunderbird, Apple Mail, Outlook, and many more. "
|
219 |
-
msgstr "Als je niet goed bent in HTML/CSS raad ik je sterk aan om het standaard sjabloon te laten zoals hij is. Het is getest op verschillende en populaire e-mailclients, zoals Gmail, Yahoo Mail, Hotmail / Live, Thunderbird, Apple Mail, Outlook, en nog veel meer."
|
220 |
-
|
221 |
-
#: wpbe.php:190
|
222 |
-
msgid "If you have any problem or any suggestions to improve this plugin, please let me know."
|
223 |
-
msgstr "Als je problemen tegenkomt of suggesties hebt om deze plugin te verbeteren, laat het me weten."
|
224 |
-
|
225 |
-
#: wpbe.php:192
|
226 |
-
msgid "Email template preview"
|
227 |
-
msgstr "E-mail sjabloon vooraf bekijken"
|
228 |
-
|
229 |
-
#: wpbe.php:193
|
230 |
-
msgid "An email preview has been successfully sent to "
|
231 |
-
msgstr "E-mail voorbeeld succesvol verstuurd naar"
|
232 |
-
|
233 |
-
#: wpbe.php:195
|
234 |
-
msgid "An error occured while sending email. Please check your server configuration."
|
235 |
-
msgstr "Er is een fout opgetreden bij het verzenden van de e-mail. Controleer de server configuratie."
|
236 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
langs/wp-better-emails.mo
CHANGED
Binary file
|
langs/wp-better-emails.pot
CHANGED
@@ -1,234 +1,195 @@
|
|
1 |
-
#
|
2 |
-
# Copyright (C) 2010
|
3 |
# This file is distributed under the same license as the package.
|
4 |
-
# FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
|
5 |
-
#
|
6 |
msgid ""
|
7 |
msgstr ""
|
8 |
-
"Project-Id-Version: \n"
|
9 |
"Report-Msgid-Bugs-To: http://wordpress.org/tag/wp-better-emails\n"
|
10 |
-
"POT-Creation-Date:
|
11 |
-
"PO-Revision-Date: 2010-11-29 16:44+0100\n"
|
12 |
-
"Last-Translator: Nicolas Lemoine <nico@yamoy.org>\n"
|
13 |
-
"Language-Team: LANGUAGE <LL@li.org>\n"
|
14 |
"MIME-Version: 1.0\n"
|
15 |
-
"Content-Type: text/plain; charset=
|
16 |
"Content-Transfer-Encoding: 8bit\n"
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
msgstr "Propulsé par Wordpress"
|
21 |
-
|
22 |
-
#: email_template.php:34
|
23 |
-
msgid "Date"
|
24 |
-
msgstr "Date"
|
25 |
-
|
26 |
-
#: email_template.php:34
|
27 |
-
msgid "Email sent the"
|
28 |
-
msgstr "Email envoyé le"
|
29 |
-
|
30 |
-
#: email_template.php:35
|
31 |
-
msgid "Contact"
|
32 |
-
msgstr "Contact"
|
33 |
-
|
34 |
-
#: email_template.php:35
|
35 |
-
msgid "For any request, please contact"
|
36 |
-
msgstr "Pour toute demande, contactez"
|
37 |
|
38 |
#: wpbe-options.php:2
|
39 |
-
|
40 |
-
|
|
|
41 |
|
42 |
#: wpbe-options.php:9
|
43 |
-
msgid "
|
44 |
-
msgstr "
|
45 |
-
|
46 |
-
#: wpbe-options.php:10
|
47 |
-
msgid "Template options"
|
48 |
-
msgstr "Options du modèle"
|
49 |
-
|
50 |
-
#: wpbe-options.php:11
|
51 |
-
msgid "Help & support"
|
52 |
-
msgstr "Aide & support"
|
53 |
-
|
54 |
-
#: wpbe-options.php:14
|
55 |
-
msgid "Change the Wordpress default behavior when sending emails to users (i.e. comment notifications, lost password, etc.), set your own sender name and email address."
|
56 |
-
msgstr "Modifiez le comportement par défaut de Wordpress lors de l'envoi d'emails aux utilisateurs (notifications, mot de passe perdu, etc.), configurez votre propre nom d'envoyeur et adresse email d'envoyeur."
|
57 |
-
|
58 |
-
#: wpbe-options.php:17
|
59 |
-
msgid "From name"
|
60 |
-
msgstr "Nom"
|
61 |
|
62 |
-
#: wpbe-options.php:
|
63 |
-
|
64 |
-
|
65 |
-
msgstr "requis"
|
66 |
|
67 |
-
#: wpbe-options.php:
|
68 |
-
msgid "
|
69 |
-
msgstr "
|
70 |
|
71 |
-
#: wpbe-options.php:
|
72 |
-
msgid "Template
|
73 |
-
msgstr "
|
74 |
|
75 |
-
#: wpbe-options.php:
|
76 |
-
msgid "
|
77 |
-
msgstr "
|
78 |
|
79 |
-
#: wpbe-options.php:
|
80 |
-
msgid "
|
81 |
-
msgstr "
|
82 |
|
83 |
-
#: wpbe-options.php:
|
84 |
-
msgid "
|
85 |
-
msgstr "
|
86 |
|
87 |
#: wpbe-options.php:35
|
88 |
-
msgid "
|
89 |
-
msgstr "
|
90 |
|
91 |
-
#: wpbe-options.php:
|
92 |
-
msgid "
|
93 |
-
msgstr "
|
94 |
|
95 |
-
#: wpbe-options.php:
|
96 |
-
msgid "
|
97 |
msgstr ""
|
98 |
|
99 |
-
#: wpbe-options.php:
|
100 |
-
msgid "
|
101 |
msgstr ""
|
102 |
|
103 |
-
#: wpbe-options.php:
|
104 |
-
msgid "
|
105 |
msgstr ""
|
106 |
|
107 |
-
#: wpbe-options.php:
|
108 |
-
msgid "
|
109 |
msgstr ""
|
110 |
|
111 |
-
#: wpbe-options.php:
|
112 |
-
msgid "
|
113 |
msgstr ""
|
114 |
|
115 |
-
#:
|
116 |
-
msgid "
|
117 |
msgstr ""
|
118 |
|
119 |
-
#:
|
120 |
-
msgid "
|
121 |
msgstr ""
|
122 |
|
123 |
-
#:
|
124 |
-
msgid "
|
125 |
msgstr ""
|
126 |
|
127 |
-
#:
|
128 |
-
msgid "
|
129 |
msgstr ""
|
130 |
|
131 |
-
#: wpbe
|
132 |
-
msgid "
|
133 |
msgstr ""
|
134 |
|
135 |
-
#: wpbe
|
136 |
-
msgid "
|
137 |
msgstr ""
|
138 |
|
139 |
-
#: wpbe
|
140 |
-
msgid "
|
141 |
msgstr ""
|
142 |
|
143 |
-
#: wpbe
|
144 |
-
msgid "
|
145 |
msgstr ""
|
146 |
|
147 |
-
#: wpbe
|
148 |
-
msgid "
|
149 |
msgstr ""
|
150 |
|
151 |
-
#: wpbe
|
152 |
-
msgid "
|
153 |
msgstr ""
|
154 |
|
155 |
-
#: wpbe
|
156 |
-
msgid "
|
157 |
msgstr ""
|
158 |
|
159 |
-
#: wpbe
|
160 |
-
msgid "
|
161 |
msgstr ""
|
162 |
|
163 |
-
#: wpbe
|
164 |
-
msgid "
|
165 |
msgstr ""
|
166 |
|
167 |
-
#: wpbe
|
168 |
-
msgid "
|
169 |
msgstr ""
|
170 |
|
171 |
-
#: wpbe
|
172 |
-
msgid "
|
173 |
msgstr ""
|
174 |
|
175 |
-
#: wpbe.php:
|
176 |
-
msgid "
|
177 |
msgstr ""
|
178 |
|
179 |
-
#: wpbe.php:
|
180 |
-
msgid "
|
181 |
msgstr ""
|
182 |
|
183 |
-
#: wpbe.php:
|
184 |
-
msgid "
|
185 |
msgstr ""
|
186 |
|
187 |
-
#: wpbe.php:
|
188 |
-
msgid "
|
189 |
msgstr ""
|
190 |
|
191 |
-
#: wpbe.php:
|
192 |
-
msgid "
|
193 |
msgstr ""
|
194 |
|
195 |
-
#: wpbe.php:
|
196 |
-
msgid "
|
197 |
msgstr ""
|
198 |
|
199 |
-
#: wpbe.php:
|
200 |
-
msgid "
|
201 |
msgstr ""
|
202 |
|
203 |
-
#: wpbe.php:
|
204 |
-
msgid "
|
205 |
msgstr ""
|
206 |
|
207 |
-
#: wpbe.php:
|
208 |
-
msgid "
|
209 |
msgstr ""
|
210 |
|
211 |
-
#: wpbe.php:
|
212 |
-
msgid "
|
213 |
msgstr ""
|
214 |
|
215 |
-
#: wpbe.php:
|
216 |
-
msgid "
|
217 |
msgstr ""
|
218 |
|
219 |
-
#: wpbe.php:
|
220 |
-
msgid "
|
221 |
msgstr ""
|
222 |
|
223 |
-
#: wpbe.php:
|
224 |
-
msgid "
|
225 |
msgstr ""
|
226 |
|
227 |
-
#: wpbe.php:
|
228 |
-
msgid "
|
229 |
msgstr ""
|
230 |
|
231 |
-
#: wpbe.php:
|
232 |
-
msgid "
|
233 |
msgstr ""
|
234 |
|
1 |
+
# Copyright (C) 2010
|
|
|
2 |
# This file is distributed under the same license as the package.
|
|
|
|
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
+
"Project-Id-Version: WP Better Emails\n"
|
6 |
"Report-Msgid-Bugs-To: http://wordpress.org/tag/wp-better-emails\n"
|
7 |
+
"POT-Creation-Date: 2011-09-06 23:22:41+00:00\n"
|
|
|
|
|
|
|
8 |
"MIME-Version: 1.0\n"
|
9 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
11 |
+
"PO-Revision-Date: 2011-09-12 17:37+0100\n"
|
12 |
+
"Last-Translator: \n"
|
13 |
+
"Language-Team: Team <plugins@artyshow-studio.fr>\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
#: wpbe-options.php:2
|
16 |
+
#: wpbe.php:158
|
17 |
+
msgid "Email settings"
|
18 |
+
msgstr ""
|
19 |
|
20 |
#: wpbe-options.php:9
|
21 |
+
msgid "Set your own sender name and email address. Default Wordpress values will be used if empty."
|
22 |
+
msgstr ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
|
24 |
+
#: wpbe-options.php:12
|
25 |
+
msgid "Name"
|
26 |
+
msgstr ""
|
|
|
27 |
|
28 |
+
#: wpbe-options.php:16
|
29 |
+
msgid "Email address"
|
30 |
+
msgstr ""
|
31 |
|
32 |
+
#: wpbe-options.php:22
|
33 |
+
msgid "HTML Template"
|
34 |
+
msgstr ""
|
35 |
|
36 |
+
#: wpbe-options.php:24
|
37 |
+
msgid "Live template preview"
|
38 |
+
msgstr ""
|
39 |
|
40 |
+
#: wpbe-options.php:24
|
41 |
+
msgid "Live preview"
|
42 |
+
msgstr ""
|
43 |
|
44 |
+
#: wpbe-options.php:26
|
45 |
+
msgid "Edit the HTML email template if you want to customize it. You might have a look at <a href="#" id="wpbe_help">help tab</a> for further information."
|
46 |
+
msgstr ""
|
47 |
|
48 |
#: wpbe-options.php:35
|
49 |
+
msgid "Send an email preview to"
|
50 |
+
msgstr ""
|
51 |
|
52 |
+
#: wpbe-options.php:39
|
53 |
+
msgid "Send"
|
54 |
+
msgstr ""
|
55 |
|
56 |
+
#: wpbe-options.php:41
|
57 |
+
msgid "You must save your template before sending an email preview."
|
58 |
msgstr ""
|
59 |
|
60 |
+
#: wpbe-options.php:46
|
61 |
+
msgid "Save Changes"
|
62 |
msgstr ""
|
63 |
|
64 |
+
#: wpbe-options.php:52
|
65 |
+
msgid "Support & bug report"
|
66 |
msgstr ""
|
67 |
|
68 |
+
#: wpbe-options.php:53
|
69 |
+
msgid "If you have any idea to improve this plugin or any bug to report, please email me at : <a href=\"mailto:plugins@artyshow-studio.fr?subject=[wp-better-emails]\">plugins@artyshow-studio.fr</a>"
|
70 |
msgstr ""
|
71 |
|
72 |
+
#: wpbe-options.php:55
|
73 |
+
msgid "You like this plugin ? You use it in a business context ? Please, consider a <a href=\"%s\" target=\"_blank\" rel=\"external\">donation</a>."
|
74 |
msgstr ""
|
75 |
|
76 |
+
#: templates/template-1.php:33
|
77 |
+
msgid "Date"
|
78 |
msgstr ""
|
79 |
|
80 |
+
#: templates/template-1.php:33
|
81 |
+
msgid "Email sent"
|
82 |
msgstr ""
|
83 |
|
84 |
+
#: templates/template-1.php:34
|
85 |
+
msgid "Contact"
|
86 |
msgstr ""
|
87 |
|
88 |
+
#: templates/template-1.php:34
|
89 |
+
msgid "For any requests, please contact"
|
90 |
msgstr ""
|
91 |
|
92 |
+
#: wpbe.php:131
|
93 |
+
msgid "Settings"
|
94 |
msgstr ""
|
95 |
|
96 |
+
#: wpbe.php:147
|
97 |
+
msgid "WP Better Emails requires WordPress 2.8 or newer."
|
98 |
msgstr ""
|
99 |
|
100 |
+
#: wpbe.php:147
|
101 |
+
msgid "Upgrade your Wordpress installation."
|
102 |
msgstr ""
|
103 |
|
104 |
+
#: wpbe.php:158
|
105 |
+
msgid "WP Better Emails"
|
106 |
msgstr ""
|
107 |
|
108 |
+
#: wpbe.php:228
|
109 |
+
msgid "Please enter a valid sender email address."
|
110 |
msgstr ""
|
111 |
|
112 |
+
#: wpbe.php:238
|
113 |
+
msgid "Template is empty"
|
114 |
msgstr ""
|
115 |
|
116 |
+
#: wpbe.php:241
|
117 |
+
msgid "No content tag found. The %content% tag is required in your template"
|
118 |
msgstr ""
|
119 |
|
120 |
+
#: wpbe.php:259
|
121 |
+
msgid "Please enter an email"
|
122 |
msgstr ""
|
123 |
|
124 |
+
#: wpbe.php:261
|
125 |
+
msgid "Please enter a valid email"
|
126 |
msgstr ""
|
127 |
|
128 |
+
#: wpbe.php:262
|
129 |
+
msgid "Hey !"
|
130 |
msgstr ""
|
131 |
|
132 |
+
#: wpbe.php:264
|
133 |
+
msgid "This is a sample email to test your HTML template."
|
134 |
msgstr ""
|
135 |
|
136 |
+
#: wpbe.php:266
|
137 |
+
msgid "If you're not skilled in HTML/CSS email coding, I strongly recommend to leave the default template as it is. It has been tested on various and popular email clients like Gmail, Yahoo Mail, Hotmail/Live, Thunderbird, Apple Mail, Outlook, and many more."
|
138 |
msgstr ""
|
139 |
|
140 |
+
#: wpbe.php:268
|
141 |
+
msgid "If you have any problems or any suggestions to improve this plugin, please let me know."
|
142 |
msgstr ""
|
143 |
|
144 |
+
#: wpbe.php:269
|
145 |
+
msgid "Email template preview"
|
146 |
msgstr ""
|
147 |
|
148 |
+
#: wpbe.php:270
|
149 |
+
msgid "An email preview has been successfully sent to %s"
|
150 |
msgstr ""
|
151 |
|
152 |
+
#: wpbe.php:273
|
153 |
+
msgid "An error occured while sending email. Please check your server configuration."
|
154 |
msgstr ""
|
155 |
|
156 |
+
#: wpbe.php:410
|
157 |
+
msgid "Some dynamic tags can be included in your email template :"
|
158 |
msgstr ""
|
159 |
|
160 |
+
#: wpbe.php:412
|
161 |
+
msgid "<strong>%content%</strong> : will be replaced with the message content."
|
162 |
msgstr ""
|
163 |
|
164 |
+
#: wpbe.php:413
|
165 |
+
msgid "NOTE: The content tag is <strong>required</strong>, WP Better Emails will be automatically desactivated if no content tag is found."
|
166 |
msgstr ""
|
167 |
|
168 |
+
#: wpbe.php:414
|
169 |
+
msgid "<strong>%blog_url%</strong> : will be replaced with your blog URL."
|
170 |
msgstr ""
|
171 |
|
172 |
+
#: wpbe.php:415
|
173 |
+
msgid "<strong>%home_url%</strong> : will be replaced with your home URL."
|
174 |
msgstr ""
|
175 |
|
176 |
+
#: wpbe.php:416
|
177 |
+
msgid "<strong>%blog_name%</strong> : will be replaced with your blog name."
|
178 |
msgstr ""
|
179 |
|
180 |
+
#: wpbe.php:417
|
181 |
+
msgid "<strong>%blog_description%</strong> : will be replaced with your blog description."
|
182 |
msgstr ""
|
183 |
|
184 |
+
#: wpbe.php:418
|
185 |
+
msgid "<strong>%admin_email%</strong> : will be replaced with admin email."
|
186 |
msgstr ""
|
187 |
|
188 |
+
#: wpbe.php:419
|
189 |
+
msgid "<strong>%date%</strong> : will be replaced with current date, as formatted in <a href=\"options-general.php\">general options</a>."
|
190 |
msgstr ""
|
191 |
|
192 |
+
#: wpbe.php:420
|
193 |
+
msgid "<strong>%time%</strong> : will be replaced with current time, as formatted in <a href=\"options-general.php\">general options</a>."
|
194 |
msgstr ""
|
195 |
|
markitup/jquery.markitup.js
DELETED
@@ -1,565 +0,0 @@
|
|
1 |
-
// ----------------------------------------------------------------------------
|
2 |
-
// markItUp! Universal MarkUp Engine, JQuery plugin
|
3 |
-
// v 1.1.x
|
4 |
-
// Dual licensed under the MIT and GPL licenses.
|
5 |
-
// ----------------------------------------------------------------------------
|
6 |
-
// Copyright (C) 2007-2010 Jay Salvat
|
7 |
-
// http://markitup.jaysalvat.com/
|
8 |
-
// ----------------------------------------------------------------------------
|
9 |
-
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
10 |
-
// of this software and associated documentation files (the "Software"), to deal
|
11 |
-
// in the Software without restriction, including without limitation the rights
|
12 |
-
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
13 |
-
// copies of the Software, and to permit persons to whom the Software is
|
14 |
-
// furnished to do so, subject to the following conditions:
|
15 |
-
//
|
16 |
-
// The above copyright notice and this permission notice shall be included in
|
17 |
-
// all copies or substantial portions of the Software.
|
18 |
-
//
|
19 |
-
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
20 |
-
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
21 |
-
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
22 |
-
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
23 |
-
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
24 |
-
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
25 |
-
// THE SOFTWARE.
|
26 |
-
// ----------------------------------------------------------------------------
|
27 |
-
|
28 |
-
(function($) {
|
29 |
-
$.fn.markItUp = function(settings, extraSettings) {
|
30 |
-
var options, ctrlKey, shiftKey, altKey;
|
31 |
-
ctrlKey = shiftKey = altKey = false;
|
32 |
-
|
33 |
-
options = { id: '',
|
34 |
-
nameSpace: '',
|
35 |
-
root: '',
|
36 |
-
previewInWindow: '', // 'width=800, height=600, resizable=yes, scrollbars=yes'
|
37 |
-
previewAutoRefresh: true,
|
38 |
-
previewPosition: 'before',
|
39 |
-
previewTemplatePath: '~/templates/preview.html',
|
40 |
-
previewParserPath: '',
|
41 |
-
previewParserVar: 'data',
|
42 |
-
resizeHandle: true,
|
43 |
-
beforeInsert: '',
|
44 |
-
afterInsert: '',
|
45 |
-
onEnter: {},
|
46 |
-
onShiftEnter: {},
|
47 |
-
onCtrlEnter: {},
|
48 |
-
onTab: {},
|
49 |
-
markupSet: [ { /* set */ } ]
|
50 |
-
};
|
51 |
-
$.extend(options, settings, extraSettings);
|
52 |
-
|
53 |
-
// compute markItUp! path
|
54 |
-
if (!options.root) {
|
55 |
-
$('script').each(function(a, tag) {
|
56 |
-
miuScript = $(tag).get(0).src.match(/(.*)jquery\.markitup(\.pack)?\.js$/);
|
57 |
-
if (miuScript !== null) {
|
58 |
-
options.root = miuScript[1];
|
59 |
-
}
|
60 |
-
});
|
61 |
-
}
|
62 |
-
|
63 |
-
return this.each(function() {
|
64 |
-
var $$, textarea, levels, scrollPosition, caretPosition, caretOffset,
|
65 |
-
clicked, hash, header, footer, previewWindow, template, iFrame, abort;
|
66 |
-
$$ = $(this);
|
67 |
-
textarea = this;
|
68 |
-
levels = [];
|
69 |
-
abort = false;
|
70 |
-
scrollPosition = caretPosition = 0;
|
71 |
-
caretOffset = -1;
|
72 |
-
|
73 |
-
options.previewParserPath = localize(options.previewParserPath);
|
74 |
-
options.previewTemplatePath = localize(options.previewTemplatePath);
|
75 |
-
|
76 |
-
// apply the computed path to ~/
|
77 |
-
function localize(data, inText) {
|
78 |
-
if (inText) {
|
79 |
-
return data.replace(/("|')~\//g, "$1"+options.root);
|
80 |
-
}
|
81 |
-
return data.replace(/^~\//, options.root);
|
82 |
-
}
|
83 |
-
|
84 |
-
// init and build editor
|
85 |
-
function init() {
|
86 |
-
id = ''; nameSpace = '';
|
87 |
-
if (options.id) {
|
88 |
-
id = 'id="'+options.id+'"';
|
89 |
-
} else if ($$.attr("id")) {
|
90 |
-
id = 'id="markItUp'+($$.attr("id").substr(0, 1).toUpperCase())+($$.attr("id").substr(1))+'"';
|
91 |
-
|
92 |
-
}
|
93 |
-
if (options.nameSpace) {
|
94 |
-
nameSpace = 'class="'+options.nameSpace+'"';
|
95 |
-
}
|
96 |
-
$$.wrap('<div '+nameSpace+'></div>');
|
97 |
-
$$.wrap('<div '+id+' class="markItUp"></div>');
|
98 |
-
$$.wrap('<div class="markItUpContainer"></div>');
|
99 |
-
$$.addClass("markItUpEditor");
|
100 |
-
|
101 |
-
// add the header before the textarea
|
102 |
-
header = $('<div class="markItUpHeader"></div>').insertBefore($$);
|
103 |
-
$(dropMenus(options.markupSet)).appendTo(header);
|
104 |
-
|
105 |
-
// add the footer after the textarea
|
106 |
-
footer = $('<div class="markItUpFooter"></div>').insertAfter($$);
|
107 |
-
|
108 |
-
// add the resize handle after textarea
|
109 |
-
if (options.resizeHandle === true && $.browser.safari !== true) {
|
110 |
-
resizeHandle = $('<div class="markItUpResizeHandle"></div>')
|
111 |
-
.insertAfter($$)
|
112 |
-
.bind("mousedown", function(e) {
|
113 |
-
var h = $$.height(), y = e.clientY, mouseMove, mouseUp;
|
114 |
-
mouseMove = function(e) {
|
115 |
-
$$.css("height", Math.max(20, e.clientY+h-y)+"px");
|
116 |
-
return false;
|
117 |
-
};
|
118 |
-
mouseUp = function(e) {
|
119 |
-
$("html").unbind("mousemove", mouseMove).unbind("mouseup", mouseUp);
|
120 |
-
return false;
|
121 |
-
};
|
122 |
-
$("html").bind("mousemove", mouseMove).bind("mouseup", mouseUp);
|
123 |
-
});
|
124 |
-
footer.append(resizeHandle);
|
125 |
-
}
|
126 |
-
|
127 |
-
// listen key events
|
128 |
-
$$.keydown(keyPressed).keyup(keyPressed);
|
129 |
-
|
130 |
-
// bind an event to catch external calls
|
131 |
-
$$.bind("insertion", function(e, settings) {
|
132 |
-
if (settings.target !== false) {
|
133 |
-
get();
|
134 |
-
}
|
135 |
-
if (textarea === $.markItUp.focused) {
|
136 |
-
markup(settings);
|
137 |
-
}
|
138 |
-
});
|
139 |
-
|
140 |
-
// remember the last focus
|
141 |
-
$$.focus(function() {
|
142 |
-
$.markItUp.focused = this;
|
143 |
-
});
|
144 |
-
}
|
145 |
-
|
146 |
-
// recursively build header with dropMenus from markupset
|
147 |
-
function dropMenus(markupSet) {
|
148 |
-
var ul = $('<ul></ul>'), i = 0;
|
149 |
-
$('li:hover > ul', ul).css('display', 'block');
|
150 |
-
$.each(markupSet, function() {
|
151 |
-
var button = this, t = '', title, li, j;
|
152 |
-
title = (button.key) ? (button.name||'')+' [Ctrl+'+button.key+']' : (button.name||'');
|
153 |
-
key = (button.key) ? 'accesskey="'+button.key+'"' : '';
|
154 |
-
if (button.separator) {
|
155 |
-
li = $('<li class="markItUpSeparator">'+(button.separator||'')+'</li>').appendTo(ul);
|
156 |
-
} else {
|
157 |
-
i++;
|
158 |
-
for (j = levels.length -1; j >= 0; j--) {
|
159 |
-
t += levels[j]+"-";
|
160 |
-
}
|
161 |
-
li = $('<li class="markItUpButton markItUpButton'+t+(i)+' '+(button.className||'')+'"><a href="" '+key+' title="'+title+'">'+(button.name||'')+'</a></li>')
|
162 |
-
.bind("contextmenu", function() { // prevent contextmenu on mac and allow ctrl+click
|
163 |
-
return false;
|
164 |
-
}).click(function() {
|
165 |
-
return false;
|
166 |
-
}).bind("focusin", function(){
|
167 |
-
$$.focus();
|
168 |
-
}).mousedown(function() {
|
169 |
-
if (button.call) {
|
170 |
-
eval(button.call)();
|
171 |
-
}
|
172 |
-
setTimeout(function() { markup(button) },1);
|
173 |
-
return false;
|
174 |
-
}).hover(function() {
|
175 |
-
$('> ul', this).show();
|
176 |
-
$(document).one('click', function() { // close dropmenu if click outside
|
177 |
-
$('ul ul', header).hide();
|
178 |
-
}
|
179 |
-
);
|
180 |
-
}, function() {
|
181 |
-
$('> ul', this).hide();
|
182 |
-
}
|
183 |
-
).appendTo(ul);
|
184 |
-
if (button.dropMenu) {
|
185 |
-
levels.push(i);
|
186 |
-
$(li).addClass('markItUpDropMenu').append(dropMenus(button.dropMenu));
|
187 |
-
}
|
188 |
-
}
|
189 |
-
});
|
190 |
-
levels.pop();
|
191 |
-
return ul;
|
192 |
-
}
|
193 |
-
|
194 |
-
// markItUp! markups
|
195 |
-
function magicMarkups(string) {
|
196 |
-
if (string) {
|
197 |
-
string = string.toString();
|
198 |
-
string = string.replace(/\(\!\(([\s\S]*?)\)\!\)/g,
|
199 |
-
function(x, a) {
|
200 |
-
var b = a.split('|!|');
|
201 |
-
if (altKey === true) {
|
202 |
-
return (b[1] !== undefined) ? b[1] : b[0];
|
203 |
-
} else {
|
204 |
-
return (b[1] === undefined) ? "" : b[0];
|
205 |
-
}
|
206 |
-
}
|
207 |
-
);
|
208 |
-
// [![prompt]!], [![prompt:!:value]!]
|
209 |
-
string = string.replace(/\[\!\[([\s\S]*?)\]\!\]/g,
|
210 |
-
function(x, a) {
|
211 |
-
var b = a.split(':!:');
|
212 |
-
if (abort === true) {
|
213 |
-
return false;
|
214 |
-
}
|
215 |
-
value = prompt(b[0], (b[1]) ? b[1] : '');
|
216 |
-
if (value === null) {
|
217 |
-
abort = true;
|
218 |
-
}
|
219 |
-
return value;
|
220 |
-
}
|
221 |
-
);
|
222 |
-
return string;
|
223 |
-
}
|
224 |
-
return "";
|
225 |
-
}
|
226 |
-
|
227 |
-
// prepare action
|
228 |
-
function prepare(action) {
|
229 |
-
if ($.isFunction(action)) {
|
230 |
-
action = action(hash);
|
231 |
-
}
|
232 |
-
return magicMarkups(action);
|
233 |
-
}
|
234 |
-
|
235 |
-
// build block to insert
|
236 |
-
function build(string) {
|
237 |
-
openWith = prepare(clicked.openWith);
|
238 |
-
placeHolder = prepare(clicked.placeHolder);
|
239 |
-
replaceWith = prepare(clicked.replaceWith);
|
240 |
-
closeWith = prepare(clicked.closeWith);
|
241 |
-
if (replaceWith !== "") {
|
242 |
-
block = openWith + replaceWith + closeWith;
|
243 |
-
} else if (selection === '' && placeHolder !== '') {
|
244 |
-
block = openWith + placeHolder + closeWith;
|
245 |
-
} else {
|
246 |
-
block = openWith + (string||selection) + closeWith;
|
247 |
-
}
|
248 |
-
return { block:block,
|
249 |
-
openWith:openWith,
|
250 |
-
replaceWith:replaceWith,
|
251 |
-
placeHolder:placeHolder,
|
252 |
-
closeWith:closeWith
|
253 |
-
};
|
254 |
-
}
|
255 |
-
|
256 |
-
// define markup to insert
|
257 |
-
function markup(button) {
|
258 |
-
var len, j, n, i;
|
259 |
-
hash = clicked = button;
|
260 |
-
get();
|
261 |
-
|
262 |
-
$.extend(hash, { line:"",
|
263 |
-
root:options.root,
|
264 |
-
textarea:textarea,
|
265 |
-
selection:(selection||''),
|
266 |
-
caretPosition:caretPosition,
|
267 |
-
ctrlKey:ctrlKey,
|
268 |
-
shiftKey:shiftKey,
|
269 |
-
altKey:altKey
|
270 |
-
}
|
271 |
-
);
|
272 |
-
// callbacks before insertion
|
273 |
-
prepare(options.beforeInsert);
|
274 |
-
prepare(clicked.beforeInsert);
|
275 |
-
if (ctrlKey === true && shiftKey === true) {
|
276 |
-
prepare(clicked.beforeMultiInsert);
|
277 |
-
}
|
278 |
-
$.extend(hash, { line:1 });
|
279 |
-
|
280 |
-
if (ctrlKey === true && shiftKey === true) {
|
281 |
-
lines = selection.split(/\r?\n/);
|
282 |
-
for (j = 0, n = lines.length, i = 0; i < n; i++) {
|
283 |
-
if ($.trim(lines[i]) !== '') {
|
284 |
-
$.extend(hash, { line:++j, selection:lines[i] } );
|
285 |
-
lines[i] = build(lines[i]).block;
|
286 |
-
} else {
|
287 |
-
lines[i] = "";
|
288 |
-
}
|
289 |
-
}
|
290 |
-
string = { block:lines.join('\n')};
|
291 |
-
start = caretPosition;
|
292 |
-
len = string.block.length + (($.browser.opera) ? n-1 : 0);
|
293 |
-
} else if (ctrlKey === true) {
|
294 |
-
string = build(selection);
|
295 |
-
start = caretPosition + string.openWith.length;
|
296 |
-
len = string.block.length - string.openWith.length - string.closeWith.length;
|
297 |
-
len -= fixIeBug(string.block);
|
298 |
-
} else if (shiftKey === true) {
|
299 |
-
string = build(selection);
|
300 |
-
start = caretPosition;
|
301 |
-
len = string.block.length;
|
302 |
-
len -= fixIeBug(string.block);
|
303 |
-
} else {
|
304 |
-
string = build(selection);
|
305 |
-
start = caretPosition + string.block.length ;
|
306 |
-
len = 0;
|
307 |
-
start -= fixIeBug(string.block);
|
308 |
-
}
|
309 |
-
if ((selection === '' && string.replaceWith === '')) {
|
310 |
-
caretOffset += fixOperaBug(string.block);
|
311 |
-
|
312 |
-
start = caretPosition + string.openWith.length;
|
313 |
-
len = string.block.length - string.openWith.length - string.closeWith.length;
|
314 |
-
|
315 |
-
caretOffset = $$.val().substring(caretPosition, $$.val().length).length;
|
316 |
-
caretOffset -= fixOperaBug($$.val().substring(0, caretPosition));
|
317 |
-
}
|
318 |
-
$.extend(hash, { caretPosition:caretPosition, scrollPosition:scrollPosition } );
|
319 |
-
|
320 |
-
if (string.block !== selection && abort === false) {
|
321 |
-
insert(string.block);
|
322 |
-
set(start, len);
|
323 |
-
} else {
|
324 |
-
caretOffset = -1;
|
325 |
-
}
|
326 |
-
get();
|
327 |
-
|
328 |
-
$.extend(hash, { line:'', selection:selection });
|
329 |
-
|
330 |
-
// callbacks after insertion
|
331 |
-
if (ctrlKey === true && shiftKey === true) {
|
332 |
-
prepare(clicked.afterMultiInsert);
|
333 |
-
}
|
334 |
-
prepare(clicked.afterInsert);
|
335 |
-
prepare(options.afterInsert);
|
336 |
-
|
337 |
-
// refresh preview if opened
|
338 |
-
if (previewWindow && options.previewAutoRefresh) {
|
339 |
-
refreshPreview();
|
340 |
-
}
|
341 |
-
|
342 |
-
// reinit keyevent
|
343 |
-
shiftKey = altKey = ctrlKey = abort = false;
|
344 |
-
}
|
345 |
-
|
346 |
-
// Substract linefeed in Opera
|
347 |
-
function fixOperaBug(string) {
|
348 |
-
if ($.browser.opera) {
|
349 |
-
return string.length - string.replace(/\n*/g, '').length;
|
350 |
-
}
|
351 |
-
return 0;
|
352 |
-
}
|
353 |
-
// Substract linefeed in IE
|
354 |
-
function fixIeBug(string) {
|
355 |
-
if ($.browser.msie) {
|
356 |
-
return string.length - string.replace(/\r/g, '').length;
|
357 |
-
}
|
358 |
-
return 0;
|
359 |
-
}
|
360 |
-
|
361 |
-
// add markup
|
362 |
-
function insert(block) {
|
363 |
-
if (document.selection) {
|
364 |
-
var newSelection = document.selection.createRange();
|
365 |
-
newSelection.text = block;
|
366 |
-
} else {
|
367 |
-
textarea.value = textarea.value.substring(0, caretPosition) + block + textarea.value.substring(caretPosition + selection.length, textarea.value.length);
|
368 |
-
}
|
369 |
-
}
|
370 |
-
|
371 |
-
// set a selection
|
372 |
-
function set(start, len) {
|
373 |
-
if (textarea.createTextRange){
|
374 |
-
// quick fix to make it work on Opera 9.5
|
375 |
-
if ($.browser.opera && $.browser.version >= 9.5 && len == 0) {
|
376 |
-
return false;
|
377 |
-
}
|
378 |
-
range = textarea.createTextRange();
|
379 |
-
range.collapse(true);
|
380 |
-
range.moveStart('character', start);
|
381 |
-
range.moveEnd('character', len);
|
382 |
-
range.select();
|
383 |
-
} else if (textarea.setSelectionRange ){
|
384 |
-
textarea.setSelectionRange(start, start + len);
|
385 |
-
}
|
386 |
-
textarea.scrollTop = scrollPosition;
|
387 |
-
textarea.focus();
|
388 |
-
}
|
389 |
-
|
390 |
-
// get the selection
|
391 |
-
function get() {
|
392 |
-
textarea.focus();
|
393 |
-
|
394 |
-
scrollPosition = textarea.scrollTop;
|
395 |
-
if (document.selection) {
|
396 |
-
selection = document.selection;
|
397 |
-
if ($.browser.msie) { // ie
|
398 |
-
var range = selection.createRange();
|
399 |
-
var stored_range = range.duplicate();
|
400 |
-
stored_range.moveToElementText(textarea);
|
401 |
-
stored_range.setEndPoint('EndToEnd', range);
|
402 |
-
var s = stored_range.text.length - range.text.length;
|
403 |
-
|
404 |
-
caretPosition = s - (textarea.value.substr(0, s).length - textarea.value.substr(0, s).replace(/\r/g, '').length);
|
405 |
-
selection = range.text;
|
406 |
-
} else { // opera
|
407 |
-
caretPosition = textarea.selectionStart;
|
408 |
-
}
|
409 |
-
} else { // gecko & webkit
|
410 |
-
caretPosition = textarea.selectionStart;
|
411 |
-
selection = textarea.value.substring(caretPosition, textarea.selectionEnd);
|
412 |
-
}
|
413 |
-
return selection;
|
414 |
-
}
|
415 |
-
|
416 |
-
// open preview window
|
417 |
-
function preview() {
|
418 |
-
if (!previewWindow || previewWindow.closed) {
|
419 |
-
if (options.previewInWindow) {
|
420 |
-
previewWindow = window.open('', 'preview', options.previewInWindow);
|
421 |
-
$(window).unload(function() {
|
422 |
-
previewWindow.close();
|
423 |
-
});
|
424 |
-
} else {
|
425 |
-
iFrame = $('<iframe class="markItUpPreviewFrame"></iframe>');
|
426 |
-
if (options.previewPosition == 'after') {
|
427 |
-
iFrame.insertAfter(footer);
|
428 |
-
} else {
|
429 |
-
iFrame.insertBefore(header);
|
430 |
-
}
|
431 |
-
previewWindow = iFrame[iFrame.length - 1].contentWindow || frame[iFrame.length - 1];
|
432 |
-
}
|
433 |
-
} else if (altKey === true) {
|
434 |
-
if (iFrame) {
|
435 |
-
iFrame.remove();
|
436 |
-
} else {
|
437 |
-
previewWindow.close();
|
438 |
-
}
|
439 |
-
previewWindow = iFrame = false;
|
440 |
-
}
|
441 |
-
if (!options.previewAutoRefresh) {
|
442 |
-
refreshPreview();
|
443 |
-
}
|
444 |
-
if (options.previewInWindow) {
|
445 |
-
previewWindow.focus();
|
446 |
-
}
|
447 |
-
}
|
448 |
-
|
449 |
-
// refresh Preview window
|
450 |
-
function refreshPreview() {
|
451 |
-
renderPreview();
|
452 |
-
}
|
453 |
-
|
454 |
-
function renderPreview() {
|
455 |
-
var phtml;
|
456 |
-
if (options.previewParserPath !== '') {
|
457 |
-
$.ajax( {
|
458 |
-
type: 'POST',
|
459 |
-
url: options.previewParserPath,
|
460 |
-
data: options.previewParserVar+'='+encodeURIComponent($$.val()),
|
461 |
-
success: function(data) {
|
462 |
-
writeInPreview( localize(data, 1) );
|
463 |
-
}
|
464 |
-
} );
|
465 |
-
} else {
|
466 |
-
if (!template) {
|
467 |
-
$.ajax( {
|
468 |
-
url: options.previewTemplatePath,
|
469 |
-
success: function(data) {
|
470 |
-
writeInPreview( localize(data, 1).replace(/<!-- content -->/g, $$.val()) );
|
471 |
-
}
|
472 |
-
} );
|
473 |
-
}
|
474 |
-
}
|
475 |
-
return false;
|
476 |
-
}
|
477 |
-
|
478 |
-
function writeInPreview(data) {
|
479 |
-
if (previewWindow.document) {
|
480 |
-
try {
|
481 |
-
sp = previewWindow.document.documentElement.scrollTop
|
482 |
-
} catch(e) {
|
483 |
-
sp = 0;
|
484 |
-
}
|
485 |
-
previewWindow.document.open();
|
486 |
-
previewWindow.document.write(data);
|
487 |
-
previewWindow.document.close();
|
488 |
-
previewWindow.document.documentElement.scrollTop = sp;
|
489 |
-
}
|
490 |
-
}
|
491 |
-
|
492 |
-
// set keys pressed
|
493 |
-
function keyPressed(e) {
|
494 |
-
shiftKey = e.shiftKey;
|
495 |
-
altKey = e.altKey;
|
496 |
-
ctrlKey = (!(e.altKey && e.ctrlKey)) ? e.ctrlKey : false;
|
497 |
-
|
498 |
-
if (e.type === 'keydown') {
|
499 |
-
if (ctrlKey === true) {
|
500 |
-
li = $("a[accesskey="+String.fromCharCode(e.keyCode)+"]", header).parent('li');
|
501 |
-
if (li.length !== 0) {
|
502 |
-
ctrlKey = false;
|
503 |
-
setTimeout(function() {
|
504 |
-
li.triggerHandler('mousedown');
|
505 |
-
},1);
|
506 |
-
return false;
|
507 |
-
}
|
508 |
-
}
|
509 |
-
if (e.keyCode === 13 || e.keyCode === 10) { // Enter key
|
510 |
-
if (ctrlKey === true) { // Enter + Ctrl
|
511 |
-
ctrlKey = false;
|
512 |
-
markup(options.onCtrlEnter);
|
513 |
-
return options.onCtrlEnter.keepDefault;
|
514 |
-
} else if (shiftKey === true) { // Enter + Shift
|
515 |
-
shiftKey = false;
|
516 |
-
markup(options.onShiftEnter);
|
517 |
-
return options.onShiftEnter.keepDefault;
|
518 |
-
} else { // only Enter
|
519 |
-
markup(options.onEnter);
|
520 |
-
return options.onEnter.keepDefault;
|
521 |
-
}
|
522 |
-
}
|
523 |
-
if (e.keyCode === 9) { // Tab key
|
524 |
-
if (shiftKey == true || ctrlKey == true || altKey == true) {
|
525 |
-
return false;
|
526 |
-
}
|
527 |
-
if (caretOffset !== -1) {
|
528 |
-
get();
|
529 |
-
caretOffset = $$.val().length - caretOffset;
|
530 |
-
set(caretOffset, 0);
|
531 |
-
caretOffset = -1;
|
532 |
-
return false;
|
533 |
-
} else {
|
534 |
-
markup(options.onTab);
|
535 |
-
return options.onTab.keepDefault;
|
536 |
-
}
|
537 |
-
}
|
538 |
-
}
|
539 |
-
}
|
540 |
-
|
541 |
-
init();
|
542 |
-
});
|
543 |
-
};
|
544 |
-
|
545 |
-
$.fn.markItUpRemove = function() {
|
546 |
-
return this.each(function() {
|
547 |
-
var $$ = $(this).unbind().removeClass('markItUpEditor');
|
548 |
-
$$.parent('div').parent('div.markItUp').parent('div').replaceWith($$);
|
549 |
-
}
|
550 |
-
);
|
551 |
-
};
|
552 |
-
|
553 |
-
$.markItUp = function(settings) {
|
554 |
-
var options = { target:false };
|
555 |
-
$.extend(options, settings);
|
556 |
-
if (options.target) {
|
557 |
-
return $(options.target).each(function() {
|
558 |
-
$(this).focus();
|
559 |
-
$(this).trigger('insertion', [options]);
|
560 |
-
});
|
561 |
-
} else {
|
562 |
-
$('textarea').trigger('insertion', [options]);
|
563 |
-
}
|
564 |
-
};
|
565 |
-
})(jQuery);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
markitup/sets/html/images/bold.png
DELETED
Binary file
|
markitup/sets/html/images/clean.png
DELETED
Binary file
|
markitup/sets/html/images/h1.png
DELETED
Binary file
|
markitup/sets/html/images/h2.png
DELETED
Binary file
|
markitup/sets/html/images/h3.png
DELETED
Binary file
|
markitup/sets/html/images/h4.png
DELETED
Binary file
|
markitup/sets/html/images/h5.png
DELETED
Binary file
|
markitup/sets/html/images/h6.png
DELETED
Binary file
|
markitup/sets/html/images/image.png
DELETED
Binary file
|
markitup/sets/html/images/italic.png
DELETED
Binary file
|
markitup/sets/html/images/link.png
DELETED
Binary file
|
markitup/sets/html/images/list-bullet.png
DELETED
Binary file
|
markitup/sets/html/images/list-item.png
DELETED
Binary file
|
markitup/sets/html/images/list-numeric.png
DELETED
Binary file
|
markitup/sets/html/images/paragraph.png
DELETED
Binary file
|
markitup/sets/html/images/picture.png
DELETED
Binary file
|
markitup/sets/html/images/preview.png
DELETED
Binary file
|
markitup/sets/html/images/stroke.png
DELETED
Binary file
|
markitup/sets/html/readme.txt
DELETED
@@ -1,11 +0,0 @@
|
|
1 |
-
Markup language:
|
2 |
-
Html
|
3 |
-
|
4 |
-
Description:
|
5 |
-
A basic Html markup set with Headings, Paragraph, Bold, Italic, Stroke through, Picture, Link, List, Clean button, Preview button.
|
6 |
-
|
7 |
-
Install:
|
8 |
-
- Download the zip file
|
9 |
-
- Unzip it in your markItUp! sets folder
|
10 |
-
- Modify your JS link to point at this set.js
|
11 |
-
- Modify your CSS link to point at this style.css
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
markitup/sets/html/set.js
DELETED
@@ -1,39 +0,0 @@
|
|
1 |
-
// ----------------------------------------------------------------------------
|
2 |
-
// markItUp!
|
3 |
-
// ----------------------------------------------------------------------------
|
4 |
-
// Copyright (C) 2008 Jay Salvat
|
5 |
-
// http://markitup.jaysalvat.com/
|
6 |
-
// ----------------------------------------------------------------------------
|
7 |
-
// Html tags
|
8 |
-
// http://en.wikipedia.org/wiki/html
|
9 |
-
// ----------------------------------------------------------------------------
|
10 |
-
// Basic set. Feel free to add more tags
|
11 |
-
// ----------------------------------------------------------------------------
|
12 |
-
mySettings = {
|
13 |
-
onShiftEnter: {keepDefault:false, replaceWith:'<br />\n'},
|
14 |
-
onCtrlEnter: {keepDefault:false, openWith:'\n<p>', closeWith:'</p>\n'},
|
15 |
-
onTab: {keepDefault:false, openWith:' '},
|
16 |
-
markupSet: [
|
17 |
-
{name:'Heading 1', key:'1', openWith:'<h1(!( class="[![Class]!]")!)>', closeWith:'</h1>', placeHolder:'Your title here...' },
|
18 |
-
{name:'Heading 2', key:'2', openWith:'<h2(!( class="[![Class]!]")!)>', closeWith:'</h2>', placeHolder:'Your title here...' },
|
19 |
-
{name:'Heading 3', key:'3', openWith:'<h3(!( class="[![Class]!]")!)>', closeWith:'</h3>', placeHolder:'Your title here...' },
|
20 |
-
{name:'Heading 4', key:'4', openWith:'<h4(!( class="[![Class]!]")!)>', closeWith:'</h4>', placeHolder:'Your title here...' },
|
21 |
-
{name:'Heading 5', key:'5', openWith:'<h5(!( class="[![Class]!]")!)>', closeWith:'</h5>', placeHolder:'Your title here...' },
|
22 |
-
{name:'Heading 6', key:'6', openWith:'<h6(!( class="[![Class]!]")!)>', closeWith:'</h6>', placeHolder:'Your title here...' },
|
23 |
-
{name:'Paragraph', openWith:'<p(!( class="[![Class]!]")!)>', closeWith:'</p>' },
|
24 |
-
{separator:'---------------' },
|
25 |
-
{name:'Bold', key:'B', openWith:'(!(<strong>|!|<b>)!)', closeWith:'(!(</strong>|!|</b>)!)' },
|
26 |
-
{name:'Italic', key:'I', openWith:'(!(<em>|!|<i>)!)', closeWith:'(!(</em>|!|</i>)!)' },
|
27 |
-
{name:'Stroke through', key:'S', openWith:'<del>', closeWith:'</del>' },
|
28 |
-
{separator:'---------------' },
|
29 |
-
{name:'Ul', openWith:'<ul>\n', closeWith:'</ul>\n' },
|
30 |
-
{name:'Ol', openWith:'<ol>\n', closeWith:'</ol>\n' },
|
31 |
-
{name:'Li', openWith:'<li>', closeWith:'</li>' },
|
32 |
-
{separator:'---------------' },
|
33 |
-
{name:'Picture', key:'P', replaceWith:'<img src="[![Source:!:http://]!]" alt="[![Alternative text]!]" />' },
|
34 |
-
{name:'Link', key:'L', openWith:'<a href="[![Link:!:http://]!]"(!( title="[![Title]!]")!)>', closeWith:'</a>', placeHolder:'Your text to link...' },
|
35 |
-
{separator:'---------------' },
|
36 |
-
{name:'Clean', className:'clean', replaceWith:function(markitup) { return markitup.selection.replace(/<(.*?)>/g, "") } },
|
37 |
-
{name:'Preview', className:'preview', call:'preview' }
|
38 |
-
]
|
39 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
markitup/sets/html/style.css
DELETED
@@ -1,59 +0,0 @@
|
|
1 |
-
/* -------------------------------------------------------------------
|
2 |
-
// markItUp!
|
3 |
-
// By Jay Salvat - http://markitup.jaysalvat.com/
|
4 |
-
// ------------------------------------------------------------------*/
|
5 |
-
.markItUp .markItUpButton1 a {
|
6 |
-
background-image:url(images/h1.png);
|
7 |
-
}
|
8 |
-
.markItUp .markItUpButton2 a {
|
9 |
-
background-image:url(images/h2.png);
|
10 |
-
}
|
11 |
-
.markItUp .markItUpButton3 a {
|
12 |
-
background-image:url(images/h3.png);
|
13 |
-
}
|
14 |
-
.markItUp .markItUpButton4 a {
|
15 |
-
background-image:url(images/h4.png);
|
16 |
-
}
|
17 |
-
.markItUp .markItUpButton5 a {
|
18 |
-
background-image:url(images/h5.png);
|
19 |
-
}
|
20 |
-
.markItUp .markItUpButton6 a {
|
21 |
-
background-image:url(images/h6.png);
|
22 |
-
}
|
23 |
-
.markItUp .markItUpButton7 a {
|
24 |
-
background-image:url(images/paragraph.png);
|
25 |
-
}
|
26 |
-
|
27 |
-
.markItUp .markItUpButton8 a {
|
28 |
-
background-image:url(images/bold.png);
|
29 |
-
}
|
30 |
-
.markItUp .markItUpButton9 a {
|
31 |
-
background-image:url(images/italic.png);
|
32 |
-
}
|
33 |
-
.markItUp .markItUpButton10 a {
|
34 |
-
background-image:url(images/stroke.png);
|
35 |
-
}
|
36 |
-
|
37 |
-
.markItUp .markItUpButton11 a {
|
38 |
-
background-image:url(images/list-bullet.png);
|
39 |
-
}
|
40 |
-
.markItUp .markItUpButton12 a {
|
41 |
-
background-image:url(images/list-numeric.png);
|
42 |
-
}
|
43 |
-
.markItUp .markItUpButton13 a {
|
44 |
-
background-image:url(images/list-item.png);
|
45 |
-
}
|
46 |
-
|
47 |
-
.markItUp .markItUpButton14 a {
|
48 |
-
background-image:url(images/picture.png);
|
49 |
-
}
|
50 |
-
.markItUp .markItUpButton15 a {
|
51 |
-
background-image:url(images/link.png);
|
52 |
-
}
|
53 |
-
|
54 |
-
.markItUp .clean a {
|
55 |
-
background-image:url(images/clean.png);
|
56 |
-
}
|
57 |
-
.markItUp .preview a {
|
58 |
-
background-image:url(images/preview.png);
|
59 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
markitup/skins/markitup/images/bg-container.png
DELETED
Binary file
|
markitup/skins/markitup/images/bg-editor-bbcode.png
DELETED
Binary file
|
markitup/skins/markitup/images/bg-editor-dotclear.png
DELETED
Binary file
|
markitup/skins/markitup/images/bg-editor-html.png
DELETED
Binary file
|
markitup/skins/markitup/images/bg-editor-json.png
DELETED
Binary file
|
markitup/skins/markitup/images/bg-editor-markdown.png
DELETED
Binary file
|
markitup/skins/markitup/images/bg-editor-textile.png
DELETED
Binary file
|
markitup/skins/markitup/images/bg-editor-wiki.png
DELETED
Binary file
|
markitup/skins/markitup/images/bg-editor-xml.png
DELETED
Binary file
|
markitup/skins/markitup/images/bg-editor.png
DELETED
Binary file
|
markitup/skins/markitup/images/handle.png
DELETED
Binary file
|
markitup/skins/markitup/images/menu.png
DELETED
Binary file
|
markitup/skins/markitup/images/submenu.png
DELETED
Binary file
|
markitup/skins/markitup/style.css
DELETED
@@ -1,147 +0,0 @@
|
|
1 |
-
/* -------------------------------------------------------------------
|
2 |
-
// markItUp! Universal MarkUp Engine, JQuery plugin
|
3 |
-
// By Jay Salvat - http://markitup.jaysalvat.com/
|
4 |
-
// ------------------------------------------------------------------*/
|
5 |
-
.markItUp * {
|
6 |
-
margin:0px; padding:0px;
|
7 |
-
outline:none;
|
8 |
-
}
|
9 |
-
.markItUp a:link,
|
10 |
-
.markItUp a:visited {
|
11 |
-
color:#000;
|
12 |
-
text-decoration:none;
|
13 |
-
}
|
14 |
-
.markItUp {
|
15 |
-
width:700px;
|
16 |
-
margin:5px 0 5px 0;
|
17 |
-
border:5px solid #F5F5F5;
|
18 |
-
}
|
19 |
-
.markItUpContainer {
|
20 |
-
border:1px solid #3C769D;
|
21 |
-
background:#FFF url(images/bg-container.png) repeat-x top left;
|
22 |
-
padding:5px 5px 2px 5px;
|
23 |
-
font:11px Verdana, Arial, Helvetica, sans-serif;
|
24 |
-
}
|
25 |
-
.markItUpEditor {
|
26 |
-
font:12px 'Courier New', Courier, monospace;
|
27 |
-
padding:5px 5px 5px 35px;
|
28 |
-
border:3px solid #3C769D;
|
29 |
-
width:643px;
|
30 |
-
height:320px;
|
31 |
-
background:#FFF url(images/bg-editor.png) no-repeat;
|
32 |
-
clear:both;
|
33 |
-
line-height:18px;
|
34 |
-
overflow:auto;
|
35 |
-
}
|
36 |
-
.markItUpPreviewFrame {
|
37 |
-
overflow:auto;
|
38 |
-
background-color:#FFFFFF;
|
39 |
-
border:1px solid #3C769D;
|
40 |
-
width:99.9%;
|
41 |
-
height:300px;
|
42 |
-
margin:5px 0;
|
43 |
-
}
|
44 |
-
.markItUpFooter {
|
45 |
-
width:100%;
|
46 |
-
cursor:n-resize;
|
47 |
-
}
|
48 |
-
.markItUpResizeHandle {
|
49 |
-
overflow:hidden;
|
50 |
-
width:22px; height:5px;
|
51 |
-
margin-left:auto;
|
52 |
-
margin-right:auto;
|
53 |
-
background-image:url(images/handle.png);
|
54 |
-
cursor:n-resize;
|
55 |
-
}
|
56 |
-
/***************************************************************************************/
|
57 |
-
/* first row of buttons */
|
58 |
-
.markItUpHeader ul li {
|
59 |
-
list-style:none;
|
60 |
-
float:left;
|
61 |
-
position:relative;
|
62 |
-
}
|
63 |
-
.markItUpHeader ul li ul{
|
64 |
-
display:none;
|
65 |
-
}
|
66 |
-
.markItUpHeader ul li:hover > ul{
|
67 |
-
display:block;
|
68 |
-
}
|
69 |
-
.markItUpHeader ul .markItUpDropMenu {
|
70 |
-
background:transparent url(images/menu.png) no-repeat 115% 50%;
|
71 |
-
margin-right:5px;
|
72 |
-
}
|
73 |
-
.markItUpHeader ul .markItUpDropMenu li {
|
74 |
-
margin-right:0px;
|
75 |
-
}
|
76 |
-
.markItUpHeader ul .markItUpSeparator {
|
77 |
-
margin:0 10px;
|
78 |
-
width:1px;
|
79 |
-
height:16px;
|
80 |
-
overflow:hidden;
|
81 |
-
background-color:#CCC;
|
82 |
-
}
|
83 |
-
.markItUpHeader ul ul .markItUpSeparator {
|
84 |
-
width:auto; height:1px;
|
85 |
-
margin:0px;
|
86 |
-
}
|
87 |
-
/* next rows of buttons */
|
88 |
-
.markItUpHeader ul ul {
|
89 |
-
display:none;
|
90 |
-
position:absolute;
|
91 |
-
top:18px; left:0px;
|
92 |
-
background:#F5F5F5;
|
93 |
-
border:1px solid #3C769D;
|
94 |
-
height:inherit;
|
95 |
-
}
|
96 |
-
.markItUpHeader ul ul li {
|
97 |
-
float:none;
|
98 |
-
border-bottom:1px solid #3C769D;
|
99 |
-
}
|
100 |
-
.markItUpHeader ul ul .markItUpDropMenu {
|
101 |
-
background:#F5F5F5 url(images/submenu.png) no-repeat 100% 50%;
|
102 |
-
}
|
103 |
-
/* next rows of buttons */
|
104 |
-
.markItUpHeader ul ul ul {
|
105 |
-
position:absolute;
|
106 |
-
top:-1px; left:150px;
|
107 |
-
}
|
108 |
-
.markItUpHeader ul ul ul li {
|
109 |
-
float:none;
|
110 |
-
}
|
111 |
-
.markItUpHeader ul a {
|
112 |
-
display:block;
|
113 |
-
width:16px; height:16px;
|
114 |
-
text-indent:-10000px;
|
115 |
-
background-repeat:no-repeat;
|
116 |
-
padding:3px;
|
117 |
-
margin:0px;
|
118 |
-
}
|
119 |
-
.markItUpHeader ul ul a {
|
120 |
-
display:block;
|
121 |
-
padding-left:0px;
|
122 |
-
text-indent:0;
|
123 |
-
width:120px;
|
124 |
-
padding:5px 5px 5px 25px;
|
125 |
-
background-position:2px 50%;
|
126 |
-
}
|
127 |
-
.markItUpHeader ul ul a:hover {
|
128 |
-
color:#FFF;
|
129 |
-
background-color:#3C769D;
|
130 |
-
}
|
131 |
-
/***************************************************************************************/
|
132 |
-
.html .markItUpEditor {
|
133 |
-
background-image:url(images/bg-editor-html.png);
|
134 |
-
}
|
135 |
-
.markdown .markItUpEditor {
|
136 |
-
background-image:url(images/bg-editor-markdown.png);
|
137 |
-
}
|
138 |
-
.textile .markItUpEditor {
|
139 |
-
background-image:url(images/bg-editor-textile.png);
|
140 |
-
}
|
141 |
-
.bbcode .markItUpEditor {
|
142 |
-
background-image:url(images/bg-editor-bbcode.png);
|
143 |
-
}
|
144 |
-
.wiki .markItUpEditor,
|
145 |
-
.dotclear .markItUpEditor {
|
146 |
-
background-image:url(images/bg-editor-wiki.png);
|
147 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
markitup/skins/simple/images/handle.png
DELETED
Binary file
|
markitup/skins/simple/images/menu.png
DELETED
Binary file
|
markitup/skins/simple/images/submenu.png
DELETED
Binary file
|
markitup/skins/simple/style.css
DELETED
@@ -1,118 +0,0 @@
|
|
1 |
-
/* -------------------------------------------------------------------
|
2 |
-
// markItUp! Universal MarkUp Engine, JQuery plugin
|
3 |
-
// By Jay Salvat - http://markitup.jaysalvat.com/
|
4 |
-
// ------------------------------------------------------------------*/
|
5 |
-
.markItUp * {
|
6 |
-
margin:0px; padding:0px;
|
7 |
-
outline:none;
|
8 |
-
}
|
9 |
-
.markItUp a:link,
|
10 |
-
.markItUp a:visited {
|
11 |
-
color:#000;
|
12 |
-
text-decoration:none;
|
13 |
-
}
|
14 |
-
.markItUp {
|
15 |
-
width:700px;
|
16 |
-
margin:5px 0 5px 0;
|
17 |
-
}
|
18 |
-
.markItUpContainer {
|
19 |
-
font:11px Verdana, Arial, Helvetica, sans-serif;
|
20 |
-
}
|
21 |
-
.markItUpEditor {
|
22 |
-
font:12px 'Courier New', Courier, monospace;
|
23 |
-
padding:5px;
|
24 |
-
width:690px;
|
25 |
-
height:320px;
|
26 |
-
clear:both;
|
27 |
-
line-height:18px;
|
28 |
-
overflow:auto;
|
29 |
-
}
|
30 |
-
.markItUpPreviewFrame {
|
31 |
-
overflow:auto;
|
32 |
-
background-color:#FFF;
|
33 |
-
width:99.9%;
|
34 |
-
height:300px;
|
35 |
-
margin:5px 0;
|
36 |
-
}
|
37 |
-
.markItUpFooter {
|
38 |
-
width:100%;
|
39 |
-
}
|
40 |
-
.markItUpResizeHandle {
|
41 |
-
overflow:hidden;
|
42 |
-
width:22px; height:5px;
|
43 |
-
margin-left:auto;
|
44 |
-
margin-right:auto;
|
45 |
-
background-image:url(images/handle.png);
|
46 |
-
cursor:n-resize;
|
47 |
-
}
|
48 |
-
/***************************************************************************************/
|
49 |
-
/* first row of buttons */
|
50 |
-
.markItUpHeader ul li {
|
51 |
-
list-style:none;
|
52 |
-
float:left;
|
53 |
-
position:relative;
|
54 |
-
}
|
55 |
-
.markItUpHeader ul li:hover > ul{
|
56 |
-
display:block;
|
57 |
-
}
|
58 |
-
.markItUpHeader ul .markItUpDropMenu {
|
59 |
-
background:transparent url(images/menu.png) no-repeat 115% 50%;
|
60 |
-
margin-right:5px;
|
61 |
-
}
|
62 |
-
.markItUpHeader ul .markItUpDropMenu li {
|
63 |
-
margin-right:0px;
|
64 |
-
}
|
65 |
-
/* next rows of buttons */
|
66 |
-
.markItUpHeader ul ul {
|
67 |
-
display:none;
|
68 |
-
position:absolute;
|
69 |
-
top:18px; left:0px;
|
70 |
-
background:#FFF;
|
71 |
-
border:1px solid #000;
|
72 |
-
}
|
73 |
-
.markItUpHeader ul ul li {
|
74 |
-
float:none;
|
75 |
-
border-bottom:1px solid #000;
|
76 |
-
}
|
77 |
-
.markItUpHeader ul ul .markItUpDropMenu {
|
78 |
-
background:#FFF url(images/submenu.png) no-repeat 100% 50%;
|
79 |
-
}
|
80 |
-
.markItUpHeader ul .markItUpSeparator {
|
81 |
-
margin:0 10px;
|
82 |
-
width:1px;
|
83 |
-
height:16px;
|
84 |
-
overflow:hidden;
|
85 |
-
background-color:#CCC;
|
86 |
-
}
|
87 |
-
.markItUpHeader ul ul .markItUpSeparator {
|
88 |
-
width:auto; height:1px;
|
89 |
-
margin:0px;
|
90 |
-
}
|
91 |
-
/* next rows of buttons */
|
92 |
-
.markItUpHeader ul ul ul {
|
93 |
-
position:absolute;
|
94 |
-
top:-1px; left:150px;
|
95 |
-
}
|
96 |
-
.markItUpHeader ul ul ul li {
|
97 |
-
float:none;
|
98 |
-
}
|
99 |
-
.markItUpHeader ul a {
|
100 |
-
display:block;
|
101 |
-
width:16px; height:16px;
|
102 |
-
text-indent:-10000px;
|
103 |
-
background-repeat:no-repeat;
|
104 |
-
padding:3px;
|
105 |
-
margin:0px;
|
106 |
-
}
|
107 |
-
.markItUpHeader ul ul a {
|
108 |
-
display:block;
|
109 |
-
padding-left:0px;
|
110 |
-
text-indent:0;
|
111 |
-
width:120px;
|
112 |
-
padding:5px 5px 5px 25px;
|
113 |
-
background-position:2px 50%;
|
114 |
-
}
|
115 |
-
.markItUpHeader ul ul a:hover {
|
116 |
-
color:#FFF;
|
117 |
-
background-color:#000;
|
118 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
markitup/templates/preview.html
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
<!-- content -->
|
|
preview.html
ADDED
File without changes
|
readme.txt
CHANGED
@@ -1,8 +1,9 @@
|
|
1 |
=== WP Better Emails ===
|
2 |
-
|
|
|
3 |
Requires at least: 2.8
|
4 |
-
Tested up to: 3.
|
5 |
-
Stable tag: 0.
|
6 |
|
7 |
Adds a customizable good looking HTML template to all WP default plain/text emails and lets you set
|
8 |
a custom sender name and email address.
|
@@ -10,23 +11,26 @@ Adds a customizable good looking HTML template to all WP default plain/text emai
|
|
10 |
== Description ==
|
11 |
|
12 |
All emails from Wordpress (lost password, notifications, etc.) are sent by default in text/plain format. WP Better
|
13 |
-
Emails wraps them with a much better looking customizable **HTML template** and lets you also set your own **sender name** and **email address**.
|
14 |
|
15 |
* WP Better Emails comes with a default simple and clean template that has been tested on various and popular email clients
|
16 |
like Gmail, Yahoo Mail, Hotmail/Live, AOL, Outlook, Apple Mail and many more. This to ensure your emails will always display
|
17 |
nicely in your recipient mailbox. But you can of course design your own.
|
18 |
-
* WP Better Emails lets you send sample emails to test and preview your own custom template.
|
19 |
-
*
|
20 |
-
*
|
|
|
|
|
21 |
replaced when sending the email.
|
22 |
-
*
|
23 |
-
*
|
|
|
24 |
|
25 |
-
=
|
26 |
|
27 |
* Add some ads/sponsored links to every email sent with wordpress
|
28 |
* Include some banners to promote a special event or feature of your website
|
29 |
-
* Brand
|
30 |
|
31 |
= Internationalization =
|
32 |
|
@@ -34,43 +38,93 @@ WP Better Emails is currently available in :
|
|
34 |
|
35 |
* English
|
36 |
* French
|
37 |
-
*
|
|
|
38 |
|
39 |
I'm looking for translators to extend to other languages. If you have translated the plugin in your language or want to,
|
40 |
please let me know : plugins [ at ] artyshow-studio.fr
|
41 |
|
|
|
|
|
|
|
|
|
42 |
== Installation ==
|
43 |
|
44 |
1. Extract and upload the `wp-better-emails` folder to the `/wp-content/plugins/` directory
|
45 |
-
2. Activate the plugin through the 'Plugins' menu in WordPress
|
46 |
-
3. Set a sender email and name, defaults
|
47 |
4. (Optional) Edit your own email template. See the screenshot tab to have a look at the default template
|
48 |
-
5. Every
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
|
50 |
== Frequently Asked Questions ==
|
51 |
|
52 |
= What if recipient can't read HTML emails ? =
|
53 |
|
54 |
-
WP Better Emails sends all emails in both formats ('multipart', i.e. HTML and plain text) so that
|
55 |
|
56 |
= Why are the emails still sent in plain text format ? =
|
57 |
|
58 |
Be sure to include the **%content%** tag in your template. WP Better Emails wrap the content with the template, if no tag
|
59 |
is found, sending HTML emails is automatically desactivated.
|
60 |
|
61 |
-
=
|
62 |
|
63 |
-
|
64 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
|
66 |
== Screenshots ==
|
67 |
|
68 |
-
1. The default template
|
69 |
-
2.
|
70 |
-
3.
|
|
|
|
|
71 |
|
72 |
== Changelog ==
|
73 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
= 0.1.3 =
|
75 |
* Sender email and name are now optional
|
76 |
* Fixes replacing URLs of plain text content to handle https protocol
|
1 |
=== WP Better Emails ===
|
2 |
+
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=7Q49VJQNRCQ8E&lc=FR&item_name=ArtyShow&item_number=wp%2dbetter%2demails¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted
|
3 |
+
Tags: email, emails, html emails, templates, notification, wp_mail, wpmu, multisite
|
4 |
Requires at least: 2.8
|
5 |
+
Tested up to: 3.2+
|
6 |
+
Stable tag: 0.2
|
7 |
|
8 |
Adds a customizable good looking HTML template to all WP default plain/text emails and lets you set
|
9 |
a custom sender name and email address.
|
11 |
== Description ==
|
12 |
|
13 |
All emails from Wordpress (lost password, notifications, etc.) are sent by default in text/plain format. WP Better
|
14 |
+
Emails wraps them with a much better looking customizable **HTML email template** and lets you also set your own **sender name** and **email address**.
|
15 |
|
16 |
* WP Better Emails comes with a default simple and clean template that has been tested on various and popular email clients
|
17 |
like Gmail, Yahoo Mail, Hotmail/Live, AOL, Outlook, Apple Mail and many more. This to ensure your emails will always display
|
18 |
nicely in your recipient mailbox. But you can of course design your own.
|
19 |
+
* WP Better Emails lets you send sample emails to test and preview your own custom HTML email template.
|
20 |
+
* Watch your HTML email template during editing with the live preview.
|
21 |
+
* Fancy HTML editor with CodeMirror syntax highlighting.
|
22 |
+
* All emails sent by this plugin are sent as 'multipart' so that email clients that don't support HTML can read them.
|
23 |
+
* Include some dynamic tags in your template such as your blog URL, home URL, blog name, blog description, admin email or date and time. They will all be
|
24 |
replaced when sending the email.
|
25 |
+
* Add your own tags with Wordpress filters (see [FAQ](http://wordpress.org/extend/plugins/wp-better-emails/faq/) for usage).
|
26 |
+
* The default template is included as an HTML file in the plugin folder, feel free to edit it with your favorite editor.
|
27 |
+
* Clean uninstall process, doesn't leave some useless data in your database when deleted, you can easily give it a try !
|
28 |
|
29 |
+
= Example usages : =
|
30 |
|
31 |
* Add some ads/sponsored links to every email sent with wordpress
|
32 |
* Include some banners to promote a special event or feature of your website
|
33 |
+
* Brand your emails to your website or client website
|
34 |
|
35 |
= Internationalization =
|
36 |
|
38 |
|
39 |
* English
|
40 |
* French
|
41 |
+
* German - [Robert Tremmel](http://roberttremmel.de/ "Robert Tremmel")
|
42 |
+
* Hebrew - [Avi Ben-Avraham](mailto:avi@nrich.co.il "Avi Ben-Avraham")
|
43 |
|
44 |
I'm looking for translators to extend to other languages. If you have translated the plugin in your language or want to,
|
45 |
please let me know : plugins [ at ] artyshow-studio.fr
|
46 |
|
47 |
+
= Credits =
|
48 |
+
|
49 |
+
[CodeMirror](http://codemirror.net/ "CodeMirror") library
|
50 |
+
|
51 |
== Installation ==
|
52 |
|
53 |
1. Extract and upload the `wp-better-emails` folder to the `/wp-content/plugins/` directory
|
54 |
+
2. Activate the plugin through the 'Plugins' menu in the WordPress admin panel
|
55 |
+
3. (Optional) Set a sender email and name, if none, wordpress defaults will be used : 'wordpress@yourdomain.com' and 'Your Blog Title'
|
56 |
4. (Optional) Edit your own email template. See the screenshot tab to have a look at the default template
|
57 |
+
5. Every email going out from your Wordpress Blog (notifications, lost password, etc.) looks better now !
|
58 |
+
|
59 |
+
== Upgrade Notice ==
|
60 |
+
|
61 |
+
If you're using the default template provided with WP Better Emails, you should delete the plugin and reinstall it to make sure you have the lastest template improvements.
|
62 |
+
|
63 |
+
If you have customized the HTML template and want to keep it, just update.
|
64 |
+
|
65 |
+
= Manual update =
|
66 |
+
|
67 |
+
1. Delete the plugin `wp-better-emails` folder under the `/wp-content/plugins/` directory
|
68 |
+
2. Upload the last version and activate it
|
69 |
+
|
70 |
+
= Automatic update =
|
71 |
+
|
72 |
+
Just use the Wordpress automatic plugin update system
|
73 |
|
74 |
== Frequently Asked Questions ==
|
75 |
|
76 |
= What if recipient can't read HTML emails ? =
|
77 |
|
78 |
+
WP Better Emails sends all emails in both formats ('multipart', i.e. HTML and plain text) so that emails can be displayed in every email client.
|
79 |
|
80 |
= Why are the emails still sent in plain text format ? =
|
81 |
|
82 |
Be sure to include the **%content%** tag in your template. WP Better Emails wrap the content with the template, if no tag
|
83 |
is found, sending HTML emails is automatically desactivated.
|
84 |
|
85 |
+
= How does WP Better Emails interact with others plugins ? =
|
86 |
|
87 |
+
WP Better Emails wraps every "plain/text" email sent with the Wordpress function `wp_mail()`.
|
88 |
+
|
89 |
+
= I totally messed up with the template, how can I get the original one ? =
|
90 |
+
|
91 |
+
Just delete and reinstall the plugin from the admin panel.
|
92 |
+
|
93 |
+
= How can I add my own tags ? =
|
94 |
+
|
95 |
+
You can filter the tags array and add your replacements. Let's say you want to randomly display some sponsored links somewhere in your email template:
|
96 |
+
|
97 |
+
add_filter('wpbe_tags', 'add_my_tags');
|
98 |
+
function add_my_tags( $tags ) {
|
99 |
+
$ads = array('<a href="#">Sponsored link 1</a>', '<a href="#">Sponsored link 2</a>', '<a href="#">Sponsored link 3</a>');
|
100 |
+
$tags['sponsored_link'] = $ads[array_rand($ads, 1)];
|
101 |
+
return $tags;
|
102 |
+
}
|
103 |
+
|
104 |
+
The key of the array `sponsored_link` will be a new tag (`%sponsored_link%`) you can include. It will be randomly replaced with one of your sponsored links.
|
105 |
+
|
106 |
+
The example above is taking sponsored links as an additinonal content but you can imagine anything like including lastest posts, a quote of the day or whatever.
|
107 |
+
You can place this function in your functions.php theme file or in a plugin.
|
108 |
|
109 |
== Screenshots ==
|
110 |
|
111 |
+
1. The default template provided with WP Better Emails. Tested on many email clients like Gmail, Yahoo!, Live/Hotmail, etc.
|
112 |
+
2. WP Better Emails settings screen with the default WP TinyMCE editor.
|
113 |
+
3. Editor in source mode using CodeMirror syntax highlighting.
|
114 |
+
4. Live preview your template in a thickbox.
|
115 |
+
5. Help tab with information about available tags.
|
116 |
|
117 |
== Changelog ==
|
118 |
|
119 |
+
= 0.2 =
|
120 |
+
* WP TinyMCE editor support
|
121 |
+
* HTML editor with CodeMirror as a TinyMCE plugin
|
122 |
+
* Live preview (> WP 3.1)
|
123 |
+
* Include filter to add your own tag replacements
|
124 |
+
* Help moved to contextual help
|
125 |
+
* Translations for german, hebrew
|
126 |
+
* Improved template email clients support
|
127 |
+
|
128 |
= 0.1.3 =
|
129 |
* Sender email and name are now optional
|
130 |
* Fixes replacing URLs of plain text content to handle https protocol
|
screenshot-1.png
CHANGED
Binary file
|
screenshot-2.png
CHANGED
Binary file
|
screenshot-3.png
CHANGED
Binary file
|
screenshot-4.png
ADDED
Binary file
|
screenshot-5.png
ADDED
Binary file
|
templates/template-1.html
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2 |
+
<html>
|
3 |
+
<head>
|
4 |
+
<meta http-equiv="Content-Type" content="text/html;UTF-8" />
|
5 |
+
</head>
|
6 |
+
<body style="margin: 0px; background-color: #F4F3F4; font-family: Helvetica, Arial, sans-serif; font-size:12px;" text="#444444" bgcolor="#F4F3F4" link="#21759B" alink="#21759B" vlink="#21759B" marginheight="0" topmargin="0" marginwidth="0" leftmargin="0">
|
7 |
+
<table cellpadding="0" cellspacing="0" width="100%" bgcolor="#F4F3F4" border="0">
|
8 |
+
<tr>
|
9 |
+
<td style="padding:15px;">
|
10 |
+
<center>
|
11 |
+
<table width="550" cellpadding="0" bgcolor="#ffffff" cellspacing="0">
|
12 |
+
<tr>
|
13 |
+
<td align="left">
|
14 |
+
<div style="border:solid 1px #d9d9d9;">
|
15 |
+
<table id="header" width="100%" border="0" cellpadding="0" bgcolor="#ffffff" cellspacing="0" style="line-height:1.6;font-size:12px;font-family: Helvetica, Arial, sans-serif;border:solid 1px #FFFFFF;color:#444;">
|
16 |
+
<tr>
|
17 |
+
<td colspan="2" background="%blog_url%/wp-admin/images/white-grad-active.png" height="30" style="color: #ffffff;" valign="bottom">.</td>
|
18 |
+
</tr>
|
19 |
+
<tr>
|
20 |
+
<td style="line-height:32px;padding-left:30px;" valign="baseline"><span style="font-size:32px;"><a href="%blog_url%" style="text-decoration:none;" target="_blank">Wordpress 3.2.1</a></span></td>
|
21 |
+
<td style="padding-right:30px;" align="right" valign="baseline"><span style="font-size:14px;color:#777777">Un site utilisant WordPress</span></td>
|
22 |
+
</tr>
|
23 |
+
</table>
|
24 |
+
<table id="content" width="490" border="0" cellpadding="0" bgcolor="#ffffff" cellspacing="0" style="margin-top:15px;margin-right:30px; margin-left:30px;color:#444;line-height:1.6;font-size:12px;font-family: Arial, sans-serif;color: #444;">
|
25 |
+
<tr>
|
26 |
+
<td colspan="2" style="border-top: solid 1px #d9d9d9">
|
27 |
+
<div style="padding:15px 0;">
|
28 |
+
Hey !<br />
|
29 |
+
|
30 |
+
<br />
|
31 |
+
Das ist eine Test-E-Mail zur Vorschau Ihrer Design-Vorlage in HTML.<br />
|
32 |
+
<br />
|
33 |
+
Sollten Sie wenig Erfahrung mit HTML/CSS-Codes haben, empfehle ich Ihnen, die Standard-Einstellungen der Design-Vorlage beizubehalten. Es wurde in gebräuchlichen E-Mail-Anwendungen getestet. Zum Beispiel: Gmail, Yahoo Mail, Hotmail/Live, Thunderbird, Apple Mail, Outlook und viele andere.<br />
|
34 |
+
<br />
|
35 |
+
Sollten bei Ihnen Probleme auftreten oder haben Sie Verbesserungsvorschläge für das Plug-in? Kontaktieren Sie mich.
|
36 |
+
</div>
|
37 |
+
</td>
|
38 |
+
</tr>
|
39 |
+
</table>
|
40 |
+
<table id="footer" width="490" border="0" cellpadding="0" bgcolor="#ffffff" cellspacing="0" style="line-height:1.5;font-size:12px;font-family: Arial, sans-serif;margin-right:30px;margin-left:30px;">
|
41 |
+
<tr style="font-size:11px;color:#999999;">
|
42 |
+
<td style="border-top: solid 1px #d9d9d9;" colspan="2">
|
43 |
+
<img style="padding-top:28px;" height="16" width="16" src="%blog_url%/wp-admin/images/wp-logo.png" align="right" alt="WP" />
|
44 |
+
<div style="padding-top:15px; padding-bottom:1px;"><img height="13" width="13" style="vertical-align: middle;" src="%blog_url%/wp-admin/images/date-button.gif" alt="Datum" /> Email sent %date% @ %time%</div>
|
45 |
+
<div><img height="12" width="12" style="vertical-align: middle;" src="%blog_url%/wp-admin/images/comment-grey-bubble.png" alt="Kontakt" /> For any requests, please contact <a href="mailto:plugins@artyshow-studio.fr">plugins@artyshow-studio.fr</a></div>
|
46 |
+
</td>
|
47 |
+
</tr>
|
48 |
+
<tr>
|
49 |
+
<td colspan="2" height="15" style="color: #ffffff;">.</td>
|
50 |
+
</tr>
|
51 |
+
</table>
|
52 |
+
</div>
|
53 |
+
</td>
|
54 |
+
</tr>
|
55 |
+
</table>
|
56 |
+
</center>
|
57 |
+
</td>
|
58 |
+
</tr>
|
59 |
+
</table>
|
60 |
+
</body>
|
61 |
+
</html>
|
templates/template-1.php
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$template = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3 |
+
<html>
|
4 |
+
<head>
|
5 |
+
<meta http-equiv="Content-Type" content="text/html;' . get_option('blog_charset') . '" />
|
6 |
+
</head>
|
7 |
+
<body style="margin: 0px; background-color: #F4F3F4; font-family: Helvetica, Arial, sans-serif; font-size:12px;" text="#444444" bgcolor="#F4F3F4" link="#21759B" alink="#21759B" vlink="#21759B" marginheight="0" topmargin="0" marginwidth="0" leftmargin="0">
|
8 |
+
<table cellpadding="0" cellspacing="0" width="100%" bgcolor="#F4F3F4" border="0">
|
9 |
+
<tr>
|
10 |
+
<td style="padding:15px;">
|
11 |
+
<center>
|
12 |
+
<table width="550" cellpadding="0" bgcolor="#ffffff" cellspacing="0">
|
13 |
+
<tr>
|
14 |
+
<td align="left">
|
15 |
+
<div style="border:solid 1px #d9d9d9;">
|
16 |
+
<table id="header" width="100%" border="0" cellpadding="0" bgcolor="#ffffff" cellspacing="0" style="line-height:1.6;font-size:12px;font-family: Helvetica, Arial, sans-serif;border:solid 1px #FFFFFF;color:#444;">
|
17 |
+
<tr>
|
18 |
+
<td colspan="2" background="' . admin_url('images/white-grad-active.png') . '" height="30" style="color:#ffffff;" valign="bottom">.</td>
|
19 |
+
</tr>
|
20 |
+
<tr>
|
21 |
+
<td style="line-height:32px;padding-left:30px;" valign="baseline"><span style="font-size:32px;"><a href="%blog_url%" style="text-decoration:none;" target="_blank">%blog_name%</a></span></td>
|
22 |
+
<td style="padding-right:30px;" align="right" valign="baseline"><span style="font-size:14px;color:#777777">%blog_description%</span></td>
|
23 |
+
</tr>
|
24 |
+
</table>
|
25 |
+
<table id="content" width="490" border="0" cellpadding="0" bgcolor="#ffffff" cellspacing="0" style="margin-top:15px;margin-right:30px; margin-left:30px;color:#444;line-height:1.6;font-size:12px;font-family: Arial, sans-serif;color: #444;">
|
26 |
+
<tr>
|
27 |
+
<td colspan="2" style="border-top: solid 1px #d9d9d9">
|
28 |
+
<div style="padding:15px 0;">
|
29 |
+
%content%
|
30 |
+
</div>
|
31 |
+
</td>
|
32 |
+
</tr>
|
33 |
+
</table>
|
34 |
+
<table id="footer" width="490" border="0" cellpadding="0" bgcolor="#ffffff" cellspacing="0" style="line-height:1.5;font-size:12px;font-family: Arial, sans-serif;margin-right:30px;margin-left:30px;">
|
35 |
+
<tr style="font-size:11px;color:#999999;">
|
36 |
+
<td style="border-top: solid 1px #d9d9d9;" colspan="2">
|
37 |
+
<img style="padding-top:28px;" height="16" width="16" src="'. admin_url('/images/wp-logo.png') . '" align="right" alt="WP" />
|
38 |
+
<div style="padding-top:15px; padding-bottom:1px;"><img height="13" width="13" style="vertical-align: middle;" src="' . admin_url('images/date-button.gif') . '" alt="' . esc_attr__('Date', 'wp-better-emails') . '" /> ' . esc_attr__('Email sent', 'wp-better-emails') . ' %date% @ %time%</div>
|
39 |
+
<div><img height="12" width="12" style="vertical-align: middle;" src="' . admin_url('images/comment-grey-bubble.png') . '" alt="' . esc_attr__('Contact', 'wp-better-emails') . '" /> ' . __('For any requests, please contact', 'wp-better-emails') . ' <a href="mailto:%admin_email%">%admin_email%</a></div>
|
40 |
+
</td>
|
41 |
+
</tr>
|
42 |
+
<tr>
|
43 |
+
<td colspan="2" style="color:#ffffff;" height="15">.</td>
|
44 |
+
</tr>
|
45 |
+
</table>
|
46 |
+
</div>
|
47 |
+
</td>
|
48 |
+
</tr>
|
49 |
+
</table>
|
50 |
+
</center>
|
51 |
+
</td>
|
52 |
+
</tr>
|
53 |
+
</table>
|
54 |
+
</body>
|
55 |
+
</html>';
|
56 |
+
?>
|
tinymce-plugins/3.3.x/fullpage/css/fullpage.css
ADDED
@@ -0,0 +1,182 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* Hide the advanced tab */
|
2 |
+
#advanced_tab {
|
3 |
+
display: none;
|
4 |
+
}
|
5 |
+
|
6 |
+
#metatitle, #metakeywords, #metadescription, #metaauthor, #metacopyright {
|
7 |
+
width: 280px;
|
8 |
+
}
|
9 |
+
|
10 |
+
#doctype, #docencoding {
|
11 |
+
width: 200px;
|
12 |
+
}
|
13 |
+
|
14 |
+
#langcode {
|
15 |
+
width: 30px;
|
16 |
+
}
|
17 |
+
|
18 |
+
#bgimage {
|
19 |
+
width: 220px;
|
20 |
+
}
|
21 |
+
|
22 |
+
#fontface {
|
23 |
+
width: 240px;
|
24 |
+
}
|
25 |
+
|
26 |
+
#leftmargin, #rightmargin, #topmargin, #bottommargin {
|
27 |
+
width: 50px;
|
28 |
+
}
|
29 |
+
|
30 |
+
.panel_wrapper div.current {
|
31 |
+
height: 400px;
|
32 |
+
}
|
33 |
+
|
34 |
+
#stylesheet, #style {
|
35 |
+
width: 240px;
|
36 |
+
}
|
37 |
+
|
38 |
+
/* Head list classes */
|
39 |
+
|
40 |
+
.headlistwrapper {
|
41 |
+
width: 100%;
|
42 |
+
}
|
43 |
+
|
44 |
+
.addbutton, .removebutton, .moveupbutton, .movedownbutton {
|
45 |
+
border-top: 1px solid;
|
46 |
+
border-left: 1px solid;
|
47 |
+
border-bottom: 1px solid;
|
48 |
+
border-right: 1px solid;
|
49 |
+
border-color: #F0F0EE;
|
50 |
+
cursor: default;
|
51 |
+
display: block;
|
52 |
+
width: 20px;
|
53 |
+
height: 20px;
|
54 |
+
}
|
55 |
+
|
56 |
+
#doctypes {
|
57 |
+
width: 200px;
|
58 |
+
}
|
59 |
+
|
60 |
+
.addbutton:hover, .removebutton:hover, .moveupbutton:hover, .movedownbutton:hover {
|
61 |
+
border: 1px solid #0A246A;
|
62 |
+
background-color: #B6BDD2;
|
63 |
+
}
|
64 |
+
|
65 |
+
.addbutton {
|
66 |
+
background-image: url('../images/add.gif');
|
67 |
+
float: left;
|
68 |
+
margin-right: 3px;
|
69 |
+
}
|
70 |
+
|
71 |
+
.removebutton {
|
72 |
+
background-image: url('../images/remove.gif');
|
73 |
+
float: left;
|
74 |
+
}
|
75 |
+
|
76 |
+
.moveupbutton {
|
77 |
+
background-image: url('../images/move_up.gif');
|
78 |
+
float: left;
|
79 |
+
margin-right: 3px;
|
80 |
+
}
|
81 |
+
|
82 |
+
.movedownbutton {
|
83 |
+
background-image: url('../images/move_down.gif');
|
84 |
+
float: left;
|
85 |
+
}
|
86 |
+
|
87 |
+
.selected {
|
88 |
+
border: 1px solid #0A246A;
|
89 |
+
background-color: #B6BDD2;
|
90 |
+
}
|
91 |
+
|
92 |
+
.toolbar {
|
93 |
+
width: 100%;
|
94 |
+
}
|
95 |
+
|
96 |
+
#headlist {
|
97 |
+
width: 100%;
|
98 |
+
margin-top: 3px;
|
99 |
+
font-size: 11px;
|
100 |
+
}
|
101 |
+
|
102 |
+
#info, #title_element, #meta_element, #script_element, #style_element, #base_element, #link_element, #comment_element, #unknown_element {
|
103 |
+
display: none;
|
104 |
+
}
|
105 |
+
|
106 |
+
#addmenu {
|
107 |
+
position: absolute;
|
108 |
+
border: 1px solid gray;
|
109 |
+
display: none;
|
110 |
+
z-index: 100;
|
111 |
+
background-color: white;
|
112 |
+
}
|
113 |
+
|
114 |
+
#addmenu a {
|
115 |
+
display: block;
|
116 |
+
width: 100%;
|
117 |
+
line-height: 20px;
|
118 |
+
text-decoration: none;
|
119 |
+
background-color: white;
|
120 |
+
}
|
121 |
+
|
122 |
+
#addmenu a:hover {
|
123 |
+
background-color: #B6BDD2;
|
124 |
+
color: black;
|
125 |
+
}
|
126 |
+
|
127 |
+
#addmenu span {
|
128 |
+
padding-left: 10px;
|
129 |
+
padding-right: 10px;
|
130 |
+
}
|
131 |
+
|
132 |
+
#updateElementPanel {
|
133 |
+
display: none;
|
134 |
+
}
|
135 |
+
|
136 |
+
#script_element .panel_wrapper div.current {
|
137 |
+
height: 108px;
|
138 |
+
}
|
139 |
+
|
140 |
+
#style_element .panel_wrapper div.current {
|
141 |
+
height: 108px;
|
142 |
+
}
|
143 |
+
|
144 |
+
#link_element .panel_wrapper div.current {
|
145 |
+
height: 140px;
|
146 |
+
}
|
147 |
+
|
148 |
+
#element_script_value {
|
149 |
+
width: 100%;
|
150 |
+
height: 100px;
|
151 |
+
}
|
152 |
+
|
153 |
+
#element_comment_value {
|
154 |
+
width: 100%;
|
155 |
+
height: 120px;
|
156 |
+
}
|
157 |
+
|
158 |
+
#element_style_value {
|
159 |
+
width: 100%;
|
160 |
+
height: 100px;
|
161 |
+
}
|
162 |
+
|
163 |
+
#element_title, #element_script_src, #element_meta_name, #element_meta_content, #element_base_href, #element_link_href, #element_link_title {
|
164 |
+
width: 250px;
|
165 |
+
}
|
166 |
+
|
167 |
+
.updateElementButton {
|
168 |
+
margin-top: 3px;
|
169 |
+
}
|
170 |
+
|
171 |
+
/* MSIE specific styles */
|
172 |
+
|
173 |
+
* html .addbutton, * html .removebutton, * html .moveupbutton, * html .movedownbutton {
|
174 |
+
width: 22px;
|
175 |
+
height: 22px;
|
176 |
+
}
|
177 |
+
|
178 |
+
textarea {
|
179 |
+
height: 55px;
|
180 |
+
}
|
181 |
+
|
182 |
+
.panel_wrapper div.current {height:420px;}
|
tinymce-plugins/3.3.x/fullpage/editor_plugin.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
(function(){tinymce.create("tinymce.plugins.FullPagePlugin",{init:function(a,b){var c=this;c.editor=a;a.addCommand("mceFullPageProperties",function(){a.windowManager.open({file:b+"/fullpage.htm",width:430+parseInt(a.getLang("fullpage.delta_width",0)),height:495+parseInt(a.getLang("fullpage.delta_height",0)),inline:1},{plugin_url:b,head_html:c.head})});a.addButton("fullpage",{title:"fullpage.desc",cmd:"mceFullPageProperties"});a.onBeforeSetContent.add(c._setContent,c);a.onSetContent.add(c._setBodyAttribs,c);a.onGetContent.add(c._getContent,c)},getInfo:function(){return{longname:"Fullpage",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullpage",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_setBodyAttribs:function(d,a){var l,c,e,g,b,h,j,f=this.head.match(/body(.*?)>/i);if(f&&f[1]){l=f[1].match(/\s*(\w+\s*=\s*".*?"|\w+\s*=\s*'.*?'|\w+\s*=\s*\w+|\w+)\s*/g);if(l){for(c=0,e=l.length;c<e;c++){g=l[c].split("=");b=g[0].replace(/\s/,"");h=g[1];if(h){h=h.replace(/^\s+/,"").replace(/\s+$/,"");j=h.match(/^["'](.*)["']$/);if(j){h=j[1]}}else{h=b}d.dom.setAttrib(d.getBody(),"style",h)}}}},_createSerializer:function(){return new tinymce.dom.Serializer({dom:this.editor.dom,apply_source_formatting:true})},_setContent:function(d,b){var i=this,a,l,f=b.content,h,j="";if(b.format=="raw"&&i.head){return}if(b.source_view&&d.getParam("fullpage_hide_in_source_view")){return}f=f.replace(/<(\/?)BODY/gi,"<$1body");a=f.indexOf("<body");if(a!=-1){a=f.indexOf(">",a);i.head=f.substring(0,a+1);var k=0,g;i.css="";while((k=i.head.indexOf("<style",k))!=-1){k=f.indexOf(">",k)+1;if((g=i.head.indexOf("</style",k))==-1){break}i.css+=i.head.substring(k,g);k=g}l=f.indexOf("</body",a);if(l==-1){l=f.length}b.content=f.substring(a+1,l);i.foot=f.substring(l);function e(c){return c.replace(/<\/?[A-Z]+/g,function(m){return m.toLowerCase()})}i.head=e(i.head);i.foot=e(i.foot)}else{i.head="";if(d.getParam("fullpage_default_xml_pi")){i.head+='<?xml version="1.0" encoding="'+d.getParam("fullpage_default_encoding","ISO-8859-1")+'" ?>\n'}i.head+=d.getParam("fullpage_default_doctype",'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">');i.head+="\n<html>\n<head>\n<title>"+d.getParam("fullpage_default_title","Untitled document")+"</title>\n";if(h=d.getParam("fullpage_default_encoding")){i.head+='<meta http-equiv="Content-Type" content="'+h+'" />\n'}if(h=d.getParam("fullpage_default_font_family")){j+="font-family: "+h+";"}if(h=d.getParam("fullpage_default_font_size")){j+="font-size: "+h+";"}if(h=d.getParam("fullpage_default_text_color")){j+="color: "+h+";"}i.head+="</head>\n<body"+(j?' style="'+j+'"':"")+">\n";i.foot="\n</body>\n</html>"}},_getContent:function(a,c){var b=this;if(!c.source_view||!a.getParam("fullpage_hide_in_source_view")){c.content=tinymce.trim(b.head)+"\n"+tinymce.trim(c.content)+"\n"+tinymce.trim(b.foot);if(b.css){b._setStyle(a,b.css)}}},_setStyle:function(a,b){a.dom.remove("injectedCSS");var d=a.dom.doc,c=d.createElement("style");c.type="text/css";c.id="injectedCSS";if(c.styleSheet){c.styleSheet.cssText=b}else{c.appendChild(d.createTextNode(b))}d.getElementsByTagName("head")[0].appendChild(c)}});tinymce.PluginManager.add("fullpage",tinymce.plugins.FullPagePlugin)})();
|
tinymce-plugins/3.3.x/fullpage/editor_plugin_src.js
ADDED
@@ -0,0 +1,182 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* editor_plugin_src.js
|
3 |
+
*
|
4 |
+
* Copyright 2009, Moxiecode Systems AB
|
5 |
+
* Released under LGPL License.
|
6 |
+
*
|
7 |
+
* License: http://tinymce.moxiecode.com/license
|
8 |
+
* Contributing: http://tinymce.moxiecode.com/contributing
|
9 |
+
*/
|
10 |
+
|
11 |
+
(function() {
|
12 |
+
tinymce.create('tinymce.plugins.FullPagePlugin', {
|
13 |
+
init : function(ed, url) {
|
14 |
+
var t = this;
|
15 |
+
|
16 |
+
t.editor = ed;
|
17 |
+
|
18 |
+
// Register commands
|
19 |
+
ed.addCommand('mceFullPageProperties', function() {
|
20 |
+
ed.windowManager.open({
|
21 |
+
file : url + '/fullpage.htm',
|
22 |
+
width : 430 + parseInt(ed.getLang('fullpage.delta_width', 0)),
|
23 |
+
height : 495 + parseInt(ed.getLang('fullpage.delta_height', 0)),
|
24 |
+
inline : 1
|
25 |
+
}, {
|
26 |
+
plugin_url : url,
|
27 |
+
head_html : t.head
|
28 |
+
});
|
29 |
+
});
|
30 |
+
|
31 |
+
// Register buttons
|
32 |
+
ed.addButton('fullpage', {title : 'fullpage.desc', cmd : 'mceFullPageProperties'});
|
33 |
+
|
34 |
+
ed.onBeforeSetContent.add(t._setContent, t);
|
35 |
+
ed.onSetContent.add(t._setBodyAttribs, t);
|
36 |
+
ed.onGetContent.add(t._getContent, t);
|
37 |
+
},
|
38 |
+
|
39 |
+
getInfo : function() {
|
40 |
+
return {
|
41 |
+
longname : 'Fullpage',
|
42 |
+
author : 'Moxiecode Systems AB',
|
43 |
+
authorurl : 'http://tinymce.moxiecode.com',
|
44 |
+
infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullpage',
|
45 |
+
version : tinymce.majorVersion + "." + tinymce.minorVersion
|
46 |
+
};
|
47 |
+
},
|
48 |
+
|
49 |
+
// Private plugin internal methods
|
50 |
+
|
51 |
+
_setBodyAttribs : function(ed, o) {
|
52 |
+
var bdattr, i, len, kv, k, v, t, attr = this.head.match(/body(.*?)>/i);
|
53 |
+
|
54 |
+
if (attr && attr[1]) {
|
55 |
+
bdattr = attr[1].match(/\s*(\w+\s*=\s*".*?"|\w+\s*=\s*'.*?'|\w+\s*=\s*\w+|\w+)\s*/g);
|
56 |
+
|
57 |
+
if (bdattr) {
|
58 |
+
for(i = 0, len = bdattr.length; i < len; i++) {
|
59 |
+
kv = bdattr[i].split('=');
|
60 |
+
k = kv[0].replace(/\s/,'');
|
61 |
+
v = kv[1];
|
62 |
+
|
63 |
+
if (v) {
|
64 |
+
v = v.replace(/^\s+/,'').replace(/\s+$/,'');
|
65 |
+
t = v.match(/^["'](.*)["']$/);
|
66 |
+
|
67 |
+
if (t)
|
68 |
+
v = t[1];
|
69 |
+
} else
|
70 |
+
v = k;
|
71 |
+
|
72 |
+
ed.dom.setAttrib(ed.getBody(), 'style', v);
|
73 |
+
}
|
74 |
+
}
|
75 |
+
}
|
76 |
+
},
|
77 |
+
|
78 |
+
_createSerializer : function() {
|
79 |
+
return new tinymce.dom.Serializer({
|
80 |
+
dom : this.editor.dom,
|
81 |
+
apply_source_formatting : true
|
82 |
+
});
|
83 |
+
},
|
84 |
+
|
85 |
+
_setContent : function(ed, o) {
|
86 |
+
var t = this, sp, ep, c = o.content, v, st = '';
|
87 |
+
|
88 |
+
// Ignore raw updated if we already have a head, this will fix issues with undo/redo keeping the head/foot separate
|
89 |
+
if (o.format == 'raw' && t.head)
|
90 |
+
return;
|
91 |
+
|
92 |
+
if (o.source_view && ed.getParam('fullpage_hide_in_source_view'))
|
93 |
+
return;
|
94 |
+
|
95 |
+
// Parse out head, body and footer
|
96 |
+
c = c.replace(/<(\/?)BODY/gi, '<$1body');
|
97 |
+
sp = c.indexOf('<body');
|
98 |
+
|
99 |
+
if (sp != -1) {
|
100 |
+
sp = c.indexOf('>', sp);
|
101 |
+
t.head = c.substring(0, sp + 1);
|
102 |
+
|
103 |
+
// Concatenate all <style>'s text into t.css
|
104 |
+
var ss = 0, es;
|
105 |
+
t.css = '';
|
106 |
+
while ((ss = t.head.indexOf('<style', ss)) != -1) {
|
107 |
+
ss = c.indexOf('>', ss) + 1;
|
108 |
+
if ( (es = t.head.indexOf('</style', ss)) == -1)
|
109 |
+
break;
|
110 |
+
t.css += t.head.substring(ss, es);
|
111 |
+
ss = es;
|
112 |
+
}
|
113 |
+
|
114 |
+
ep = c.indexOf('</body', sp);
|
115 |
+
if (ep == -1)
|
116 |
+
ep = c.length;
|
117 |
+
|
118 |
+
o.content = c.substring(sp + 1, ep);
|
119 |
+
t.foot = c.substring(ep);
|
120 |
+
|
121 |
+
function low(s) {
|
122 |
+
return s.replace(/<\/?[A-Z]+/g, function(a) {
|
123 |
+
return a.toLowerCase();
|
124 |
+
})
|
125 |
+
};
|
126 |
+
|
127 |
+
t.head = low(t.head);
|
128 |
+
t.foot = low(t.foot);
|
129 |
+
} else {
|
130 |
+
t.head = '';
|
131 |
+
if (ed.getParam('fullpage_default_xml_pi'))
|
132 |
+
t.head += '<?xml version="1.0" encoding="' + ed.getParam('fullpage_default_encoding', 'ISO-8859-1') + '" ?>\n';
|
133 |
+
|
134 |
+
t.head += ed.getParam('fullpage_default_doctype', '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">');
|
135 |
+
t.head += '\n<html>\n<head>\n<title>' + ed.getParam('fullpage_default_title', 'Untitled document') + '</title>\n';
|
136 |
+
|
137 |
+
if (v = ed.getParam('fullpage_default_encoding'))
|
138 |
+
t.head += '<meta http-equiv="Content-Type" content="' + v + '" />\n';
|
139 |
+
|
140 |
+
if (v = ed.getParam('fullpage_default_font_family'))
|
141 |
+
st += 'font-family: ' + v + ';';
|
142 |
+
|
143 |
+
if (v = ed.getParam('fullpage_default_font_size'))
|
144 |
+
st += 'font-size: ' + v + ';';
|
145 |
+
|
146 |
+
if (v = ed.getParam('fullpage_default_text_color'))
|
147 |
+
st += 'color: ' + v + ';';
|
148 |
+
|
149 |
+
t.head += '</head>\n<body' + (st ? ' style="' + st + '"' : '') + '>\n';
|
150 |
+
t.foot = '\n</body>\n</html>';
|
151 |
+
}
|
152 |
+
},
|
153 |
+
|
154 |
+
_getContent : function(ed, o) {
|
155 |
+
var t = this;
|
156 |
+
|
157 |
+
if (!o.source_view || !ed.getParam('fullpage_hide_in_source_view')) {
|
158 |
+
o.content = tinymce.trim(t.head) + '\n' + tinymce.trim(o.content) + '\n' + tinymce.trim(t.foot);
|
159 |
+
|
160 |
+
if (t.css)
|
161 |
+
t._setStyle(ed, t.css);
|
162 |
+
}
|
163 |
+
},
|
164 |
+
|
165 |
+
_setStyle : function(ed, css) {
|
166 |
+
ed.dom.remove('injectedCSS');
|
167 |
+
var doc = ed.dom.doc, style = doc.createElement('style');
|
168 |
+
style.type = 'text/css';
|
169 |
+
style.id = 'injectedCSS';
|
170 |
+
|
171 |
+
if (style.styleSheet) // IE
|
172 |
+
style.styleSheet.cssText = css;
|
173 |
+
else // other browsers
|
174 |
+
style.appendChild(doc.createTextNode(css));
|
175 |
+
|
176 |
+
doc.getElementsByTagName('head')[0].appendChild(style);
|
177 |
+
}
|
178 |
+
});
|
179 |
+
|
180 |
+
// Register plugin
|
181 |
+
tinymce.PluginManager.add('fullpage', tinymce.plugins.FullPagePlugin);
|
182 |
+
})();
|
tinymce-plugins/3.3.x/fullpage/fullpage.htm
ADDED
@@ -0,0 +1,571 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
2 |
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
3 |
+
<head>
|
4 |
+
<title>{#fullpage_dlg.title}</title>
|
5 |
+
<script type="text/javascript" src="../../tiny_mce_popup.js"></script>
|
6 |
+
<script type="text/javascript" src="../../utils/mctabs.js"></script>
|
7 |
+
<script type="text/javascript" src="../../utils/form_utils.js"></script>
|
8 |
+
<script type="text/javascript" src="js/fullpage.js"></script>
|
9 |
+
<link href="css/fullpage.css" rel="stylesheet" type="text/css" />
|
10 |
+
</head>
|
11 |
+
<body id="advlink" style="display: none">
|
12 |
+
<form onsubmit="updateAction();return false;" name="fullpage" action="#">
|
13 |
+
<div class="tabs">
|
14 |
+
<ul>
|
15 |
+
<li id="meta_tab" class="current"><span><a href="javascript:mcTabs.displayTab('meta_tab','meta_panel');" onmousedown="return false;">{#fullpage_dlg.meta_tab}</a></span></li>
|
16 |
+
<li id="appearance_tab"><span><a href="javascript:mcTabs.displayTab('appearance_tab','appearance_panel');" onmousedown="return false;">{#fullpage_dlg.appearance_tab}</a></span></li>
|
17 |
+
<li id="advanced_tab"><span><a href="javascript:mcTabs.displayTab('advanced_tab','advanced_panel');" onmousedown="return false;">{#fullpage_dlg.advanced_tab}</a></span></li>
|
18 |
+
</ul>
|
19 |
+
</div>
|
20 |
+
|
21 |
+
<div class="panel_wrapper">
|
22 |
+
<div id="meta_panel" class="panel current">
|
23 |
+
<fieldset>
|
24 |
+
<legend>{#fullpage_dlg.meta_props}</legend>
|
25 |
+
|
26 |
+
<table border="0" cellpadding="4" cellspacing="0">
|
27 |
+
<tr>
|
28 |
+
<td class="nowrap"><label for="metatitle">{#fullpage_dlg.meta_title}</label> </td>
|
29 |
+
<td><input type="text" id="metatitle" name="metatitle" value="" class="mceFocus" /></td>
|
30 |
+
</tr>
|
31 |
+
<tr>
|
32 |
+
<td class="nowrap"><label for="metakeywords">{#fullpage_dlg.meta_keywords}</label> </td>
|
33 |
+
<td><textarea id="metakeywords" name="metakeywords" rows="4"></textarea></td>
|
34 |
+
</tr>
|
35 |
+
<tr>
|
36 |
+
<td class="nowrap"><label for="metadescription">{#fullpage_dlg.meta_description}</label> </td>
|
37 |
+
<td><textarea id="metadescription" name="metadescription" rows="4"></textarea></td>
|
38 |
+
</tr>
|
39 |
+
<tr>
|
40 |
+
<td class="nowrap"><label for="metaauthor">{#fullpage_dlg.author}</label> </td>
|
41 |
+
<td><input type="text" id="metaauthor" name="metaauthor" value="" /></td>
|
42 |
+
</tr>
|
43 |
+
<tr>
|
44 |
+
<td class="nowrap"><label for="metacopyright">{#fullpage_dlg.copyright}</label> </td>
|
45 |
+
<td><input type="text" id="metacopyright" name="metacopyright" value="" /></td>
|
46 |
+
</tr>
|
47 |
+
<tr>
|
48 |
+
<td class="nowrap"><label for="metarobots">{#fullpage_dlg.meta_robots}</label> </td>
|
49 |
+
<td>
|
50 |
+
<select id="metarobots" name="metarobots">
|
51 |
+
<option value="">{#not_set}</option>
|
52 |
+
<option value="index,follow">{#fullpage_dlg.meta_index_follow}</option>
|
53 |
+
<option value="index,nofollow">{#fullpage_dlg.meta_index_nofollow}</option>
|
54 |
+
<option value="noindex,follow">{#fullpage_dlg.meta_noindex_follow}</option>
|
55 |
+
<option value="noindex,nofollow">{#fullpage_dlg.meta_noindex_nofollow}</option>
|
56 |
+
</select>
|
57 |
+
</td>
|
58 |
+
</tr>
|
59 |
+
</table>
|
60 |
+
</fieldset>
|
61 |
+
|
62 |
+
<fieldset>
|
63 |
+
<legend>{#fullpage_dlg.langprops}</legend>
|
64 |
+
|
65 |
+
<table border="0" cellpadding="4" cellspacing="0">
|
66 |
+
<tr>
|
67 |
+
<td class="column1"><label for="docencoding">{#fullpage_dlg.encoding}</label></td>
|
68 |
+
<td>
|
69 |
+
<select id="docencoding" name="docencoding">
|
70 |
+
<option value="">{#not_set}</option>
|
71 |
+
</select>
|
72 |
+
</td>
|
73 |
+
</tr>
|
74 |
+
<tr>
|
75 |
+
<td class="nowrap"><label for="doctypes">{#fullpage_dlg.doctypes}</label> </td>
|
76 |
+
<td>
|
77 |
+
<select id="doctypes" name="doctypes">
|
78 |
+
<option value="">{#not_set}</option>
|
79 |
+
</select>
|
80 |
+
</td>
|
81 |
+
</tr>
|
82 |
+
<tr>
|
83 |
+
<td class="nowrap"><label for="langcode">{#fullpage_dlg.langcode}</label> </td>
|
84 |
+
<td><input type="text" id="langcode" name="langcode" value="" /></td>
|
85 |
+
</tr>
|
86 |
+
<tr>
|
87 |
+
<td class="column1"><label for="langdir">{#fullpage_dlg.langdir}</label></td>
|
88 |
+
<td>
|
89 |
+
<select id="langdir" name="langdir">
|
90 |
+
<option value="">{#not_set}</option>
|
91 |
+
<option value="ltr">{#fullpage_dlg.ltr}</option>
|
92 |
+
<option value="rtl">{#fullpage_dlg.rtl}</option>
|
93 |
+
</select>
|
94 |
+
</td>
|
95 |
+
</tr>
|
96 |
+
<tr>
|
97 |
+
<td class="nowrap"><label for="xml_pi">{#fullpage_dlg.xml_pi}</label> </td>
|
98 |
+
<td><input type="checkbox" id="xml_pi" name="xml_pi" class="checkbox" /></td>
|
99 |
+
</tr>
|
100 |
+
</table>
|
101 |
+
</fieldset>
|
102 |
+
</div>
|
103 |
+
|
104 |
+
<div id="appearance_panel" class="panel">
|
105 |
+
<fieldset>
|
106 |
+
<legend>{#fullpage_dlg.appearance_textprops}</legend>
|
107 |
+
|
108 |
+
<table border="0" cellpadding="4" cellspacing="0">
|
109 |
+
<tr>
|
110 |
+
<td class="column1"><label for="fontface">{#fullpage_dlg.fontface}</label></td>
|
111 |
+
<td>
|
112 |
+
<select id="fontface" name="fontface" onchange="changedStyleField(this);">
|
113 |
+
<option value="">{#not_set}</option>
|
114 |
+
</select>
|
115 |
+
</td>
|
116 |
+
</tr>
|
117 |
+
|
118 |
+
<tr>
|
119 |
+
<td class="column1"><label for="fontsize">{#fullpage_dlg.fontsize}</label></td>
|
120 |
+
<td>
|
121 |
+
<select id="fontsize" name="fontsize" onchange="changedStyleField(this);">
|
122 |
+
<option value="">{#not_set}</option>
|
123 |
+
</select>
|
124 |
+
</td>
|
125 |
+
</tr>
|
126 |
+
|
127 |
+
<tr>
|
128 |
+
<td class="column1"><label for="textcolor">{#fullpage_dlg.textcolor}</label></td>
|
129 |
+
<td>
|
130 |
+
<table border="0" cellpadding="0" cellspacing="0">
|
131 |
+
<tr>
|
132 |
+
<td><input id="textcolor" name="textcolor" type="text" value="" size="9" onchange="updateColor('textcolor_pick','textcolor');changedStyleField(this);" /></td>
|
133 |
+
<td id="textcolor_pickcontainer"> </td>
|
134 |
+
</tr>
|
135 |
+
</table>
|
136 |
+
</td>
|
137 |
+
</tr>
|
138 |
+
</table>
|
139 |
+
</fieldset>
|
140 |
+
|
141 |
+
<fieldset>
|
142 |
+
<legend>{#fullpage_dlg.appearance_bgprops}</legend>
|
143 |
+
|
144 |
+
<table border="0" cellpadding="4" cellspacing="0">
|
145 |
+
<tr>
|
146 |
+
<td class="column1"><label for="bgimage">{#fullpage_dlg.bgimage}</label></td>
|
147 |
+
<td>
|
148 |
+
<table border="0" cellpadding="0" cellspacing="0">
|
149 |
+
<tr>
|
150 |
+
<td><input id="bgimage" name="bgimage" type="text" value="" onchange="changedStyleField(this);" /></td>
|
151 |
+
<td id="bgimage_pickcontainer"> </td>
|
152 |
+
</tr>
|
153 |
+
</table>
|
154 |
+
</td>
|
155 |
+
</tr>
|
156 |
+
<tr>
|
157 |
+
<td class="column1"><label for="bgcolor">{#fullpage_dlg.bgcolor}</label></td>
|
158 |
+
<td>
|
159 |
+
<table border="0" cellpadding="0" cellspacing="0">
|
160 |
+
<tr>
|
161 |
+
<td><input id="bgcolor" name="bgcolor" type="text" value="" size="9" onchange="updateColor('bgcolor_pick','bgcolor');changedStyleField(this);" /></td>
|
162 |
+
<td id="bgcolor_pickcontainer"> </td>
|
163 |
+
</tr>
|
164 |
+
</table>
|
165 |
+
</td>
|
166 |
+
</tr>
|
167 |
+
</table>
|
168 |
+
</fieldset>
|
169 |
+
|
170 |
+
<fieldset>
|
171 |
+
<legend>{#fullpage_dlg.appearance_marginprops}</legend>
|
172 |
+
|
173 |
+
<table border="0" cellpadding="4" cellspacing="0">
|
174 |
+
<tr>
|
175 |
+
<td class="column1"><label for="leftmargin">{#fullpage_dlg.left_margin}</label></td>
|
176 |
+
<td><input id="leftmargin" name="leftmargin" type="text" value="" onchange="changedStyleField(this);" /></td>
|
177 |
+
<td class="column1"><label for="rightmargin">{#fullpage_dlg.right_margin}</label></td>
|
178 |
+
<td><input id="rightmargin" name="rightmargin" type="text" value="" onchange="changedStyleField(this);" /></td>
|
179 |
+
</tr>
|
180 |
+
<tr>
|
181 |
+
<td class="column1"><label for="topmargin">{#fullpage_dlg.top_margin}</label></td>
|
182 |
+
<td><input id="topmargin" name="topmargin" type="text" value="" onchange="changedStyleField(this);" /></td>
|
183 |
+
<td class="column1"><label for="bottommargin">{#fullpage_dlg.bottom_margin}</label></td>
|
184 |
+
<td><input id="bottommargin" name="bottommargin" type="text" value="" onchange="changedStyleField(this);" /></td>
|
185 |
+
</tr>
|
186 |
+
</table>
|
187 |
+
</fieldset>
|
188 |
+
|
189 |
+
<fieldset>
|
190 |
+
<legend>{#fullpage_dlg.appearance_linkprops}</legend>
|
191 |
+
|
192 |
+
<table border="0" cellpadding="4" cellspacing="0">
|
193 |
+
<tr>
|
194 |
+
<td class="column1"><label for="link_color">{#fullpage_dlg.link_color}</label></td>
|
195 |
+
<td>
|
196 |
+
<table border="0" cellpadding="0" cellspacing="0">
|
197 |
+
<tr>
|
198 |
+
<td><input id="link_color" name="link_color" type="text" value="" size="9" onchange="updateColor('link_color_pick','link_color');changedStyleField(this);" /></td>
|
199 |
+
<td id="link_color_pickcontainer"> </td>
|
200 |
+
</tr>
|
201 |
+
</table>
|
202 |
+
</td>
|
203 |
+
|
204 |
+
<td class="column1"><label for="visited_color">{#fullpage_dlg.visited_color}</label></td>
|
205 |
+
<td>
|
206 |
+
<table border="0" cellpadding="0" cellspacing="0">
|
207 |
+
<tr>
|
208 |
+
<td><input id="visited_color" name="visited_color" type="text" value="" size="9" onchange="updateColor('visited_color_pick','visited_color');changedStyleField(this);" /></td>
|
209 |
+
<td id="visited_color_pickcontainer"> </td>
|
210 |
+
</tr>
|
211 |
+
</table>
|
212 |
+
</td>
|
213 |
+
</tr>
|
214 |
+
|
215 |
+
<tr>
|
216 |
+
<td class="column1"><label for="active_color">{#fullpage_dlg.active_color}</label></td>
|
217 |
+
<td>
|
218 |
+
<table border="0" cellpadding="0" cellspacing="0">
|
219 |
+
<tr>
|
220 |
+
<td><input id="active_color" name="active_color" type="text" value="" size="9" onchange="updateColor('active_color_pick','active_color');changedStyleField(this);" /></td>
|
221 |
+
<td id="active_color_pickcontainer"> </td>
|
222 |
+
</tr>
|
223 |
+
</table>
|
224 |
+
</td>
|
225 |
+
|
226 |
+
<td> </td>
|
227 |
+
<td> </td>
|
228 |
+
|
229 |
+
<!-- <td class="column1"><label for="hover_color">{#fullpage_dlg.hover_color}</label></td>
|
230 |
+
<td>
|
231 |
+
<table border="0" cellpadding="0" cellspacing="0">
|
232 |
+
<tr>
|
233 |
+
<td><input id="hover_color" name="hover_color" type="text" value="" size="9" onchange="changedStyleField(this);" /></td>
|
234 |
+
<td id="hover_color_pickcontainer"> </td>
|
235 |
+
</tr>
|
236 |
+
</table>
|
237 |
+
</td> -->
|
238 |
+
</tr>
|
239 |
+
</table>
|
240 |
+
</fieldset>
|
241 |
+
|
242 |
+
<fieldset>
|
243 |
+
<legend>{#fullpage_dlg.appearance_style}</legend>
|
244 |
+
|
245 |
+
<table border="0" cellpadding="4" cellspacing="0">
|
246 |
+
<tr>
|
247 |
+
<td class="column1"><label for="stylesheet">{#fullpage_dlg.stylesheet}</label></td>
|
248 |
+
<td><table border="0" cellpadding="0" cellspacing="0">
|
249 |
+
<tr>
|
250 |
+
<td><input id="stylesheet" name="stylesheet" type="text" value="" /></td>
|
251 |
+
<td id="stylesheet_browsercontainer"> </td>
|
252 |
+
</tr>
|
253 |
+
</table></td>
|
254 |
+
</tr>
|
255 |
+
<tr>
|
256 |
+
<td class="column1"><label for="style">{#fullpage_dlg.style}</label></td>
|
257 |
+
<td><input id="style" name="style" type="text" value="" onchange="changedStyleField(this);" /></td>
|
258 |
+
</tr>
|
259 |
+
</table>
|
260 |
+
</fieldset>
|
261 |
+
</div>
|
262 |
+
|
263 |
+
<div id="advanced_panel" class="panel">
|
264 |
+
<div id="addmenu">
|
265 |
+
<table border="0" cellpadding="0" cellspacing="0">
|
266 |
+
<tr><td><a href="javascript:addHeadElm('title');" onmousedown="return false;"><span>{#fullpage_dlg.add_title}</span></a></td></tr>
|
267 |
+
<tr><td><a href="javascript:addHeadElm('meta');" onmousedown="return false;"><span>{#fullpage_dlg.add_meta}</span></a></td></tr>
|
268 |
+
<tr><td><a href="javascript:addHeadElm('script');" onmousedown="return false;"><span>{#fullpage_dlg.add_script}</span></a></td></tr>
|
269 |
+
<tr><td><a href="javascript:addHeadElm('style');" onmousedown="return false;"><span>{#fullpage_dlg.add_style}</span></a></td></tr>
|
270 |
+
<tr><td><a href="javascript:addHeadElm('link');" onmousedown="return false;"><span>{#fullpage_dlg.add_link}</span></a></td></tr>
|
271 |
+
<tr><td><a href="javascript:addHeadElm('base');" onmousedown="return false;"><span>{#fullpage_dlg.add_base}</span></a></td></tr>
|
272 |
+
<tr><td><a href="javascript:addHeadElm('comment');" onmousedown="return false;"><span>{#fullpage_dlg.add_comment}</span></a></td></tr>
|
273 |
+
</table>
|
274 |
+
</div>
|
275 |
+
|
276 |
+
<fieldset>
|
277 |
+
<legend>{#fullpage_dlg.head_elements}</legend>
|
278 |
+
|
279 |
+
<div class="headlistwrapper">
|
280 |
+
<div class="toolbar">
|
281 |
+
<div style="float: left">
|
282 |
+
<a id="addbutton" href="javascript:showAddMenu();" onmousedown="return false;" class="addbutton" title="{#fullpage_dlg.add}"></a>
|
283 |
+
<a href="#" onmousedown="return false;" class="removebutton" title="{#fullpage_dlg.remove}"></a>
|
284 |
+
</div>
|
285 |
+
<div style="float: right">
|
286 |
+
<a href="#" onmousedown="return false;" class="moveupbutton" title="{#fullpage_dlg.moveup}"></a>
|
287 |
+
<a href="#" onmousedown="return false;" class="movedownbutton" title="{#fullpage_dlg.movedown}"></a>
|
288 |
+
</div>
|
289 |
+
<br style="clear: both" />
|
290 |
+
</div>
|
291 |
+
<select id="headlist" size="26" onchange="updateHeadElm(this.options[this.selectedIndex].value);">
|
292 |
+
<option value="title_0"><title>Some title bla bla bla</title></option>
|
293 |
+
<option value="meta_1"><meta name="keywords">Some bla bla bla</meta></option>
|
294 |
+
<option value="meta_2"><meta name="description">Some bla bla bla bla bla bla bla bla bla</meta></option>
|
295 |
+
<option value="script_3"><script language="javascript">...</script></option>
|
296 |
+
<option value="style_4"><style>...</style></option>
|
297 |
+
<option value="base_5"><base href="." /></option>
|
298 |
+
<option value="comment_6"><!-- ... --></option>
|
299 |
+
<option value="link_7"><link href="." /></option>
|
300 |
+
</select>
|
301 |
+
</div>
|
302 |
+
</fieldset>
|
303 |
+
|
304 |
+
<fieldset id="meta_element">
|
305 |
+
<legend>{#fullpage_dlg.meta_element}</legend>
|
306 |
+
|
307 |
+
<table border="0" cellpadding="4" cellspacing="0">
|
308 |
+
<tr>
|
309 |
+
<td class="column1"><label for="element_meta_type">{#fullpage_dlg.type}</label></td>
|
310 |
+
<td><select id="element_meta_type">
|
311 |
+
<option value="name">name</option>
|
312 |
+
<option value="http-equiv">http-equiv</option>
|
313 |
+
</select></td>
|
314 |
+
</tr>
|
315 |
+
<tr>
|
316 |
+
<td class="column1"><label for="element_meta_name">{#fullpage_dlg.name}</label></td>
|
317 |
+
<td><input id="element_meta_name" name="element_meta_name" type="text" value="" /></td>
|
318 |
+
</tr>
|
319 |
+
<tr>
|
320 |
+
<td class="column1"><label for="element_meta_content">{#fullpage_dlg.content}</label></td>
|
321 |
+
<td><input id="element_meta_content" name="element_meta_content" type="text" value="" /></td>
|
322 |
+
</tr>
|
323 |
+
</table>
|
324 |
+
|
325 |
+
<input type="button" id="meta_updateelement" class="updateElementButton" name="update" value="{#update}" onclick="updateElement();" />
|
326 |
+
</fieldset>
|
327 |
+
|
328 |
+
<fieldset id="title_element">
|
329 |
+
<legend>{#fullpage_dlg.title_element}</legend>
|
330 |
+
|
331 |
+
<table border="0" cellpadding="4" cellspacing="0">
|
332 |
+
<tr>
|
333 |
+
<td class="column1"><label for="element_title">{#fullpage_dlg.meta_title}</label></td>
|
334 |
+
<td><input id="element_title" name="element_title" type="text" value="" /></td>
|
335 |
+
</tr>
|
336 |
+
</table>
|
337 |
+
|
338 |
+
<input type="button" id="title_updateelement" class="updateElementButton" name="update" value="{#update}" onclick="updateElement();" />
|
339 |
+
</fieldset>
|
340 |
+
|
341 |
+
<fieldset id="script_element">
|
342 |
+
<legend>{#fullpage_dlg.script_element}</legend>
|
343 |
+
|
344 |
+
<div class="tabs">
|
345 |
+
<ul>
|
346 |
+
<li id="script_props_tab" class="current"><span><a href="javascript:mcTabs.displayTab('script_props_tab','script_props_panel');" onmousedown="return false;">{#fullpage_dlg.properties}</a></span></li>
|
347 |
+
<li id="script_value_tab"><span><a href="javascript:mcTabs.displayTab('script_value_tab','script_value_panel');" onmousedown="return false;">{#fullpage_dlg.value}</a></span></li>
|
348 |
+
</ul>
|
349 |
+
</div>
|
350 |
+
|
351 |
+
<br style="clear: both" />
|
352 |
+
|
353 |
+
<div class="panel_wrapper">
|
354 |
+
<div id="script_props_panel" class="panel current">
|
355 |
+
<table border="0" cellpadding="4" cellspacing="0">
|
356 |
+
<tr>
|
357 |
+
<td class="column1"><label for="element_script_type">{#fullpage_dlg.type}</label></td>
|
358 |
+
<td><select id="element_script_type">
|
359 |
+
<option value="text/javascript">text/javascript</option>
|
360 |
+
<option value="text/jscript">text/jscript</option>
|
361 |
+
<option value="text/vbscript">text/vbscript</option>
|
362 |
+
<option value="text/vbs">text/vbs</option>
|
363 |
+
<option value="text/ecmascript">text/ecmascript</option>
|
364 |
+
<option value="text/xml">text/xml</option>
|
365 |
+
</select></td>
|
366 |
+
</tr>
|
367 |
+
<tr>
|
368 |
+
<td class="column1"><label for="element_script_src">{#fullpage_dlg.src}</label></td>
|
369 |
+
<td><table border="0" cellpadding="0" cellspacing="0">
|
370 |
+
<tr>
|
371 |
+
<td><input id="element_script_src" name="element_script_src" type="text" value="" /></td>
|
372 |
+
<td id="script_src_pickcontainer"> </td>
|
373 |
+
</tr>
|
374 |
+
</table></td>
|
375 |
+
</tr>
|
376 |
+
<tr>
|
377 |
+
<td class="column1"><label for="element_script_charset">{#fullpage_dlg.charset}</label></td>
|
378 |
+
<td><select id="element_script_charset"><option value="">{#not_set}</option></select></td>
|
379 |
+
</tr>
|
380 |
+
<tr>
|
381 |
+
<td class="column1"><label for="element_script_defer">{#fullpage_dlg.defer}</label></td>
|
382 |
+
<td><input type="checkbox" id="element_script_defer" name="element_script_defer" class="checkbox" /></td>
|
383 |
+
</tr>
|
384 |
+
</table>
|
385 |
+
</div>
|
386 |
+
|
387 |
+
<div id="script_value_panel" class="panel">
|
388 |
+
<textarea id="element_script_value"></textarea>
|
389 |
+
</div>
|
390 |
+
</div>
|
391 |
+
|
392 |
+
<input type="button" id="script_updateelement" class="updateElementButton" name="update" value="{#update}" onclick="updateElement();" />
|
393 |
+
</fieldset>
|
394 |
+
|
395 |
+
<fieldset id="style_element">
|
396 |
+
<legend>{#fullpage_dlg.style_element}</legend>
|
397 |
+
|
398 |
+
<div class="tabs">
|
399 |
+
<ul>
|
400 |
+
<li id="style_props_tab" class="current"><span><a href="javascript:mcTabs.displayTab('style_props_tab','style_props_panel');" onmousedown="return false;">{#fullpage_dlg.properties}</a></span></li>
|
401 |
+
<li id="style_value_tab"><span><a href="javascript:mcTabs.displayTab('style_value_tab','style_value_panel');" onmousedown="return false;">{#fullpage_dlg.value}</a></span></li>
|
402 |
+
</ul>
|
403 |
+
</div>
|
404 |
+
|
405 |
+
<br style="clear: both" />
|
406 |
+
|
407 |
+
<div class="panel_wrapper">
|
408 |
+
<div id="style_props_panel" class="panel current">
|
409 |
+
<table border="0" cellpadding="4" cellspacing="0">
|
410 |
+
<tr>
|
411 |
+
<td class="column1"><label for="element_style_type">{#fullpage_dlg.type}</label></td>
|
412 |
+
<td><select id="element_style_type">
|
413 |
+
<option value="text/css">text/css</option>
|
414 |
+
</select></td>
|
415 |
+
</tr>
|
416 |
+
<tr>
|
417 |
+
<td class="column1"><label for="element_style_media">{#fullpage_dlg.media}</label></td>
|
418 |
+
<td><select id="element_style_media"></select></td>
|
419 |
+
</tr>
|
420 |
+
</table>
|
421 |
+
</div>
|
422 |
+
|
423 |
+
<div id="style_value_panel" class="panel">
|
424 |
+
<textarea id="element_style_value"></textarea>
|
425 |
+
</div>
|
426 |
+
</div>
|
427 |
+
|
428 |
+
<input type="button" id="style_updateelement" class="updateElementButton" name="update" value="{#update}" onclick="updateElement();" />
|
429 |
+
</fieldset>
|
430 |
+
|
431 |
+
<fieldset id="base_element">
|
432 |
+
<legend>{#fullpage_dlg.base_element}</legend>
|
433 |
+
|
434 |
+
<table border="0" cellpadding="4" cellspacing="0">
|
435 |
+
<tr>
|
436 |
+
<td class="column1"><label for="element_base_href">{#fullpage_dlg.href}</label></td>
|
437 |
+
<td><input id="element_base_href" name="element_base_href" type="text" value="" /></td>
|
438 |
+
</tr>
|
439 |
+
<tr>
|
440 |
+
<td class="column1"><label for="element_base_target">{#fullpage_dlg.target}</label></td>
|
441 |
+
<td><input id="element_base_target" name="element_base_target" type="text" value="" /></td>
|
442 |
+
</tr>
|
443 |
+
</table>
|
444 |
+
|
445 |
+
<input type="button" id="base_updateelement" class="updateElementButton" name="update" value="{#update}" onclick="updateElement();" />
|
446 |
+
</fieldset>
|
447 |
+
|
448 |
+
<fieldset id="link_element">
|
449 |
+
<legend>{#fullpage_dlg.link_element}</legend>
|
450 |
+
|
451 |
+
<div class="tabs">
|
452 |
+
<ul>
|
453 |
+
<li id="link_general_tab" class="current"><span><a href="javascript:mcTabs.displayTab('link_general_tab','link_general_panel');" onmousedown="return false;">{#fullpage_dlg.general_props}</a></span></li>
|
454 |
+
<li id="link_advanced_tab"><span><a href="javascript:mcTabs.displayTab('link_advanced_tab','link_advanced_panel');" onmousedown="return false;">{#fullpage_dlg.advanced_props}</a></span></li>
|
455 |
+
</ul>
|
456 |
+
</div>
|
457 |
+
|
458 |
+
<br style="clear: both" />
|
459 |
+
|
460 |
+
<div class="panel_wrapper">
|
461 |
+
<div id="link_general_panel" class="panel current">
|
462 |
+
<table border="0" cellpadding="4" cellspacing="0">
|
463 |
+
<tr>
|
464 |
+
<td class="column1"><label for="element_link_href">{#fullpage_dlg.href}</label></td>
|
465 |
+
<td><table border="0" cellpadding="0" cellspacing="0">
|
466 |
+
<tr>
|
467 |
+
<td><input id="element_link_href" name="element_link_href" type="text" value="" /></td>
|
468 |
+
<td id="link_href_pickcontainer"> </td>
|
469 |
+
</tr>
|
470 |
+
</table></td>
|
471 |
+
</tr>
|
472 |
+
<tr>
|
473 |
+
<td class="column1"><label for="element_link_title">{#fullpage_dlg.meta_title}</label></td>
|
474 |
+
<td><input id="element_link_title" name="element_link_title" type="text" value="" /></td>
|
475 |
+
</tr>
|
476 |
+
<tr>
|
477 |
+
<td class="column1"><label for="element_link_type">{#fullpage_dlg.type}</label></td>
|
478 |
+
<td><select id="element_link_type" name="element_link_type">
|
479 |
+
<option value="text/css">text/css</option>
|
480 |
+
<option value="text/javascript">text/javascript</option>
|
481 |
+
</select></td>
|
482 |
+
</tr>
|
483 |
+
<tr>
|
484 |
+
<td class="column1"><label for="element_link_media">{#fullpage_dlg.media}</label></td>
|
485 |
+
<td><select id="element_link_media" name="element_link_media"></select></td>
|
486 |
+
</tr>
|
487 |
+
<tr>
|
488 |
+
<td><label for="element_style_rel">{#fullpage_dlg.rel}</label></td>
|
489 |
+
<td><select id="element_style_rel" name="element_style_rel">
|
490 |
+
<option value="">{#not_set}</option>
|
491 |
+
<option value="stylesheet">Stylesheet</option>
|
492 |
+
<option value="alternate">Alternate</option>
|
493 |
+
<option value="designates">Designates</option>
|
494 |
+
<option value="start">Start</option>
|
495 |
+
<option value="next">Next</option>
|
496 |
+
<option value="prev">Prev</option>
|
497 |
+
<option value="contents">Contents</option>
|
498 |
+
<option value="index">Index</option>
|
499 |
+
<option value="glossary">Glossary</option>
|
500 |
+
<option value="copyright">Copyright</option>
|
501 |
+
<option value="chapter">Chapter</option>
|
502 |
+
<option value="subsection">Subsection</option>
|
503 |
+
<option value="appendix">Appendix</option>
|
504 |
+
<option value="help">Help</option>
|
505 |
+
<option value="bookmark">Bookmark</option>
|
506 |
+
</select>
|
507 |
+
</td>
|
508 |
+
</tr>
|
509 |
+
</table>
|
510 |
+
</div>
|
511 |
+
|
512 |
+
<div id="link_advanced_panel" class="panel">
|
513 |
+
<table border="0" cellpadding="4" cellspacing="0">
|
514 |
+
<tr>
|
515 |
+
<td class="column1"><label for="element_link_charset">{#fullpage_dlg.charset}</label></td>
|
516 |
+
<td><select id="element_link_charset"><option value="">{#not_set}</option></select></td>
|
517 |
+
</tr>
|
518 |
+
<tr>
|
519 |
+
<td class="column1"><label for="element_link_hreflang">{#fullpage_dlg.hreflang}</label></td>
|
520 |
+
<td><input id="element_link_hreflang" name="element_link_hreflang" type="text" value="" /></td>
|
521 |
+
</tr>
|
522 |
+
<tr>
|
523 |
+
<td class="column1"><label for="element_link_target">{#fullpage_dlg.target}</label></td>
|
524 |
+
<td><input id="element_link_target" name="element_link_target" type="text" value="" /></td>
|
525 |
+
</tr>
|
526 |
+
<tr>
|
527 |
+
<td><label for="element_style_rev">{#fullpage_dlg.rev}</label></td>
|
528 |
+
<td><select id="element_style_rev" name="element_style_rev">
|
529 |
+
<option value="">{#not_set}</option>
|
530 |
+
<option value="alternate">Alternate</option>
|
531 |
+
<option value="designates">Designates</option>
|
532 |
+
<option value="stylesheet">Stylesheet</option>
|
533 |
+
<option value="start">Start</option>
|
534 |
+
<option value="next">Next</option>
|
535 |
+
<option value="prev">Prev</option>
|
536 |
+
<option value="contents">Contents</option>
|
537 |
+
<option value="index">Index</option>
|
538 |
+
<option value="glossary">Glossary</option>
|
539 |
+
<option value="copyright">Copyright</option>
|
540 |
+
<option value="chapter">Chapter</option>
|
541 |
+
<option value="subsection">Subsection</option>
|
542 |
+
<option value="appendix">Appendix</option>
|
543 |
+
<option value="help">Help</option>
|
544 |
+
<option value="bookmark">Bookmark</option>
|
545 |
+
</select>
|
546 |
+
</td>
|
547 |
+
</tr>
|
548 |
+
</table>
|
549 |
+
</div>
|
550 |
+
</div>
|
551 |
+
|
552 |
+
<input type="button" id="link_updateelement" class="updateElementButton" name="update" value="{#update}" onclick="updateElement();" />
|
553 |
+
</fieldset>
|
554 |
+
|
555 |
+
<fieldset id="comment_element">
|
556 |
+
<legend>{#fullpage_dlg.comment_element}</legend>
|
557 |
+
|
558 |
+
<textarea id="element_comment_value"></textarea>
|
559 |
+
|
560 |
+
<input type="button" id="comment_updateelement" class="updateElementButton" name="update" value="{#update}" onclick="updateElement();" />
|
561 |
+
</fieldset>
|
562 |
+
</div>
|
563 |
+
</div>
|
564 |
+
|
565 |
+
<div class="mceActionPanel">
|
566 |
+
<input type="submit" id="insert" name="update" value="{#update}" />
|
567 |
+
<input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" />
|
568 |
+
</div>
|
569 |
+
</form>
|
570 |
+
</body>
|
571 |
+
</html>
|
tinymce-plugins/3.3.x/fullpage/js/fullpage.js
ADDED
@@ -0,0 +1,471 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* fullpage.js
|
3 |
+
*
|
4 |
+
* Copyright 2009, Moxiecode Systems AB
|
5 |
+
* Released under LGPL License.
|
6 |
+
*
|
7 |
+
* License: http://tinymce.moxiecode.com/license
|
8 |
+
* Contributing: http://tinymce.moxiecode.com/contributing
|
9 |
+
*/
|
10 |
+
|
11 |
+
tinyMCEPopup.requireLangPack();
|
12 |
+
|
13 |
+
var doc;
|
14 |
+
|
15 |
+
var defaultDocTypes =
|
16 |
+
'XHTML 1.0 Transitional=<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">,' +
|
17 |
+
'XHTML 1.0 Frameset=<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">,' +
|
18 |
+
'XHTML 1.0 Strict=<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">,' +
|
19 |
+
'XHTML 1.1=<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">,' +
|
20 |
+
'HTML 4.01 Transitional=<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">,' +
|
21 |
+
'HTML 4.01 Strict=<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">,' +
|
22 |
+
'HTML 4.01 Frameset=<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">';
|
23 |
+
|
24 |
+
var defaultEncodings =
|
25 |
+
'Western european (iso-8859-1)=iso-8859-1,' +
|
26 |
+
'Central European (iso-8859-2)=iso-8859-2,' +
|
27 |
+
'Unicode (UTF-8)=utf-8,' +
|
28 |
+
'Chinese traditional (Big5)=big5,' +
|
29 |
+
'Cyrillic (iso-8859-5)=iso-8859-5,' +
|
30 |
+
'Japanese (iso-2022-jp)=iso-2022-jp,' +
|
31 |
+
'Greek (iso-8859-7)=iso-8859-7,' +
|
32 |
+
'Korean (iso-2022-kr)=iso-2022-kr,' +
|
33 |
+
'ASCII (us-ascii)=us-ascii';
|
34 |
+
|
35 |
+
var defaultMediaTypes =
|
36 |
+
'all=all,' +
|
37 |
+
'screen=screen,' +
|
38 |
+
'print=print,' +
|
39 |
+
'tty=tty,' +
|
40 |
+
'tv=tv,' +
|
41 |
+
'projection=projection,' +
|
42 |
+
'handheld=handheld,' +
|
43 |
+
'braille=braille,' +
|
44 |
+
'aural=aural';
|
45 |
+
|
46 |
+
var defaultFontNames = 'Arial=arial,helvetica,sans-serif;Courier New=courier new,courier,monospace;Georgia=georgia,times new roman,times,serif;Tahoma=tahoma,arial,helvetica,sans-serif;Times New Roman=times new roman,times,serif;Verdana=verdana,arial,helvetica,sans-serif;Impact=impact;WingDings=wingdings';
|
47 |
+
var defaultFontSizes = '10px,11px,12px,13px,14px,15px,16px';
|
48 |
+
|
49 |
+
function init() {
|
50 |
+
var f = document.forms['fullpage'], el = f.elements, e, i, p, doctypes, encodings, mediaTypes, fonts, ed = tinyMCEPopup.editor, dom = tinyMCEPopup.dom, style;
|
51 |
+
|
52 |
+
// Setup doctype select box
|
53 |
+
doctypes = ed.getParam("fullpage_doctypes", defaultDocTypes).split(',');
|
54 |
+
for (i=0; i<doctypes.length; i++) {
|
55 |
+
p = doctypes[i].split('=');
|
56 |
+
|
57 |
+
if (p.length > 1)
|
58 |
+
addSelectValue(f, 'doctypes', p[0], p[1]);
|
59 |
+
}
|
60 |
+
|
61 |
+
// Setup fonts select box
|
62 |
+
fonts = ed.getParam("fullpage_fonts", defaultFontNames).split(';');
|
63 |
+
for (i=0; i<fonts.length; i++) {
|
64 |
+
p = fonts[i].split('=');
|
65 |
+
|
66 |
+
if (p.length > 1)
|
67 |
+
addSelectValue(f, 'fontface', p[0], p[1]);
|
68 |
+
}
|
69 |
+
|
70 |
+
// Setup fontsize select box
|
71 |
+
fonts = ed.getParam("fullpage_fontsizes", defaultFontSizes).split(',');
|
72 |
+
for (i=0; i<fonts.length; i++)
|
73 |
+
addSelectValue(f, 'fontsize', fonts[i], fonts[i]);
|
74 |
+
|
75 |
+
// Setup mediatype select boxs
|
76 |
+
mediaTypes = ed.getParam("fullpage_media_types", defaultMediaTypes).split(',');
|
77 |
+
for (i=0; i<mediaTypes.length; i++) {
|
78 |
+
p = mediaTypes[i].split('=');
|
79 |
+
|
80 |
+
if (p.length > 1) {
|
81 |
+
addSelectValue(f, 'element_style_media', p[0], p[1]);
|
82 |
+
addSelectValue(f, 'element_link_media', p[0], p[1]);
|
83 |
+
}
|
84 |
+
}
|
85 |
+
|
86 |
+
// Setup encodings select box
|
87 |
+
encodings = ed.getParam("fullpage_encodings", defaultEncodings).split(',');
|
88 |
+
for (i=0; i<encodings.length; i++) {
|
89 |
+
p = encodings[i].split('=');
|
90 |
+
|
91 |
+
if (p.length > 1) {
|
92 |
+
addSelectValue(f, 'docencoding', p[0], p[1]);
|
93 |
+
addSelectValue(f, 'element_script_charset', p[0], p[1]);
|
94 |
+
addSelectValue(f, 'element_link_charset', p[0], p[1]);
|
95 |
+
}
|
96 |
+
}
|
97 |
+
|
98 |
+
document.getElementById('bgcolor_pickcontainer').innerHTML = getColorPickerHTML('bgcolor_pick','bgcolor');
|
99 |
+
document.getElementById('link_color_pickcontainer').innerHTML = getColorPickerHTML('link_color_pick','link_color');
|
100 |
+
//document.getElementById('hover_color_pickcontainer').innerHTML = getColorPickerHTML('hover_color_pick','hover_color');
|
101 |
+
document.getElementById('visited_color_pickcontainer').innerHTML = getColorPickerHTML('visited_color_pick','visited_color');
|
102 |
+
document.getElementById('active_color_pickcontainer').innerHTML = getColorPickerHTML('active_color_pick','active_color');
|
103 |
+
document.getElementById('textcolor_pickcontainer').innerHTML = getColorPickerHTML('textcolor_pick','textcolor');
|
104 |
+
document.getElementById('stylesheet_browsercontainer').innerHTML = getBrowserHTML('stylesheetbrowser','stylesheet','file','fullpage');
|
105 |
+
document.getElementById('link_href_pickcontainer').innerHTML = getBrowserHTML('link_href_browser','element_link_href','file','fullpage');
|
106 |
+
document.getElementById('script_src_pickcontainer').innerHTML = getBrowserHTML('script_src_browser','element_script_src','file','fullpage');
|
107 |
+
document.getElementById('bgimage_pickcontainer').innerHTML = getBrowserHTML('bgimage_browser','bgimage','image','fullpage');
|
108 |
+
|
109 |
+
// Resize some elements
|
110 |
+
if (isVisible('stylesheetbrowser'))
|
111 |
+
document.getElementById('stylesheet').style.width = '220px';
|
112 |
+
|
113 |
+
if (isVisible('link_href_browser'))
|
114 |
+
document.getElementById('element_link_href').style.width = '230px';
|
115 |
+
|
116 |
+
if (isVisible('bgimage_browser'))
|
117 |
+
document.getElementById('bgimage').style.width = '210px';
|
118 |
+
|
119 |
+
// Add iframe
|
120 |
+
dom.add(document.body, 'iframe', {id : 'documentIframe', src : 'javascript:""', style : {display : 'none'}});
|
121 |
+
doc = dom.get('documentIframe').contentWindow.document;
|
122 |
+
h = tinyMCEPopup.getWindowArg('head_html');
|
123 |
+
|
124 |
+
// Preprocess the HTML disable scripts and urls
|
125 |
+
h = h.replace(/<script>/gi, '<script type="text/javascript">');
|
126 |
+
h = h.replace(/type=([\"\'])?/gi, 'type=$1-mce-');
|
127 |
+
h = h.replace(/(src=|href=)/g, '_mce_$1');
|
128 |
+
|
129 |
+
// Write in the content in the iframe
|
130 |
+
doc.write(h + '</body></html>');
|
131 |
+
doc.close();
|
132 |
+
|
133 |
+
// Parse xml and doctype
|
134 |
+
xmlVer = getReItem(/<\?\s*?xml.*?version\s*?=\s*?"(.*?)".*?\?>/gi, h, 1);
|
135 |
+
xmlEnc = getReItem(/<\?\s*?xml.*?encoding\s*?=\s*?"(.*?)".*?\?>/gi, h, 1);
|
136 |
+
docType = getReItem(/<\!DOCTYPE.*?>/gi, h.replace(/\n/g, ''), 0).replace(/ +/g, ' ');
|
137 |
+
f.langcode.value = getReItem(/lang="(.*?)"/gi, h, 1);
|
138 |
+
|
139 |
+
// Parse title
|
140 |
+
if (e = doc.getElementsByTagName('title')[0])
|
141 |
+
el.metatitle.value = e.textContent || e.text;
|
142 |
+
|
143 |
+
// Parse meta
|
144 |
+
tinymce.each(doc.getElementsByTagName('meta'), function(n) {
|
145 |
+
var na = (n.getAttribute('name', 2) || '').toLowerCase(), va = n.getAttribute('content', 2), eq = n.getAttribute('httpEquiv', 2) || '';
|
146 |
+
|
147 |
+
e = el['meta' + na];
|
148 |
+
|
149 |
+
if (na == 'robots') {
|
150 |
+
selectByValue(f, 'metarobots', tinymce.trim(va), true, true);
|
151 |
+
return;
|
152 |
+
}
|
153 |
+
|
154 |
+
switch (eq.toLowerCase()) {
|
155 |
+
case "content-type":
|
156 |
+
tmp = getReItem(/charset\s*=\s*(.*)\s*/gi, va, 1);
|
157 |
+
|
158 |
+
// Override XML encoding
|
159 |
+
if (tmp != "")
|
160 |
+
xmlEnc = tmp;
|
161 |
+
|
162 |
+
return;
|
163 |
+
}
|
164 |
+
|
165 |
+
if (e)
|
166 |
+
e.value = va;
|
167 |
+
});
|
168 |
+
|
169 |
+
selectByValue(f, 'doctypes', docType, true, true);
|
170 |
+
selectByValue(f, 'docencoding', xmlEnc, true, true);
|
171 |
+
selectByValue(f, 'langdir', doc.body.getAttribute('dir', 2) || '', true, true);
|
172 |
+
|
173 |
+
if (xmlVer != '')
|
174 |
+
el.xml_pi.checked = true;
|
175 |
+
|
176 |
+
// Parse appearance
|
177 |
+
|
178 |
+
// Parse primary stylesheet
|
179 |
+
tinymce.each(doc.getElementsByTagName("link"), function(l) {
|
180 |
+
var m = l.getAttribute('media', 2) || '', t = l.getAttribute('type', 2) || '';
|
181 |
+
|
182 |
+
if (t == "-mce-text/css" && (m == "" || m == "screen" || m == "all") && (l.getAttribute('rel', 2) || '') == "stylesheet") {
|
183 |
+
f.stylesheet.value = l.getAttribute('_mce_href', 2) || '';
|
184 |
+
return false;
|
185 |
+
}
|
186 |
+
});
|
187 |
+
|
188 |
+
// Get from style elements
|
189 |
+
tinymce.each(doc.getElementsByTagName("style"), function(st) {
|
190 |
+
var tmp = parseStyleElement(st);
|
191 |
+
|
192 |
+
for (x=0; x<tmp.length; x++) {
|
193 |
+
if (tmp[x].rule.indexOf('a:visited') != -1 && tmp[x].data['color'])
|
194 |
+
f.visited_color.value = tmp[x].data['color'];
|
195 |
+
|
196 |
+
if (tmp[x].rule.indexOf('a:link') != -1 && tmp[x].data['color'])
|
197 |
+
f.link_color.value = tmp[x].data['color'];
|
198 |
+
|
199 |
+
if (tmp[x].rule.indexOf('a:active') != -1 && tmp[x].data['color'])
|
200 |
+
f.active_color.value = tmp[x].data['color'];
|
201 |
+
}
|
202 |
+
});
|
203 |
+
|
204 |
+
f.textcolor.value = tinyMCEPopup.dom.getAttrib(doc.body, "text");
|
205 |
+
f.active_color.value = tinyMCEPopup.dom.getAttrib(doc.body, "alink");
|
206 |
+
f.link_color.value = tinyMCEPopup.dom.getAttrib(doc.body, "link");
|
207 |
+
f.visited_color.value = tinyMCEPopup.dom.getAttrib(doc.body, "vlink");
|
208 |
+
f.bgcolor.value = tinyMCEPopup.dom.getAttrib(doc.body, "bgcolor");
|
209 |
+
f.bgimage.value = tinyMCEPopup.dom.getAttrib(doc.body, "background");
|
210 |
+
|
211 |
+
// Get from style info
|
212 |
+
style = tinyMCEPopup.dom.parseStyle(tinyMCEPopup.dom.getAttrib(doc.body, 'style'));
|
213 |
+
|
214 |
+
if (style['font-family'])
|
215 |
+
selectByValue(f, 'fontface', style['font-family'], true, true);
|
216 |
+
else
|
217 |
+
selectByValue(f, 'fontface', ed.getParam("fullpage_default_fontface", ""), true, true);
|
218 |
+
|
219 |
+
if (style['font-size'])
|
220 |
+
selectByValue(f, 'fontsize', style['font-size'], true, true);
|
221 |
+
else
|
222 |
+
selectByValue(f, 'fontsize', ed.getParam("fullpage_default_fontsize", ""), true, true);
|
223 |
+
|
224 |
+
if (style['color'])
|
225 |
+
f.textcolor.value = convertRGBToHex(style['color']);
|
226 |
+
|
227 |
+
if (style['background-image'])
|
228 |
+
f.bgimage.value = style['background-image'].replace(new RegExp("url\\('?([^']*)'?\\)", 'gi'), "$1");
|
229 |
+
|
230 |
+
if (style['background-color'])
|
231 |
+
f.bgcolor.value = style['background-color'];
|
232 |
+
|
233 |
+
if (style['margin']) {
|
234 |
+
tmp = style['margin'].replace(/[^0-9 ]/g, '');
|
235 |
+
tmp = tmp.split(/ +/);
|
236 |
+
f.topmargin.value = tmp.length > 0 ? tmp[0] : '';
|
237 |
+
f.rightmargin.value = tmp.length > 1 ? tmp[1] : tmp[0];
|
238 |
+
f.bottommargin.value = tmp.length > 2 ? tmp[2] : tmp[0];
|
239 |
+
f.leftmargin.value = tmp.length > 3 ? tmp[3] : tmp[0];
|
240 |
+
}
|
241 |
+
|
242 |
+
if (style['margin-left'])
|
243 |
+
f.leftmargin.value = style['margin-left'].replace(/[^0-9]/g, '');
|
244 |
+
|
245 |
+
if (style['margin-right'])
|
246 |
+
f.rightmargin.value = style['margin-right'].replace(/[^0-9]/g, '');
|
247 |
+
|
248 |
+
if (style['margin-top'])
|
249 |
+
f.topmargin.value = style['margin-top'].replace(/[^0-9]/g, '');
|
250 |
+
|
251 |
+
if (style['margin-bottom'])
|
252 |
+
f.bottommargin.value = style['margin-bottom'].replace(/[^0-9]/g, '');
|
253 |
+
|
254 |
+
f.style.value = tinyMCEPopup.dom.serializeStyle(style);
|
255 |
+
|
256 |
+
// Update colors
|
257 |
+
updateColor('textcolor_pick', 'textcolor');
|
258 |
+
updateColor('bgcolor_pick', 'bgcolor');
|
259 |
+
updateColor('visited_color_pick', 'visited_color');
|
260 |
+
updateColor('active_color_pick', 'active_color');
|
261 |
+
updateColor('link_color_pick', 'link_color');
|
262 |
+
}
|
263 |
+
|
264 |
+
function getReItem(r, s, i) {
|
265 |
+
var c = r.exec(s);
|
266 |
+
|
267 |
+
if (c && c.length > i)
|
268 |
+
return c[i];
|
269 |
+
|
270 |
+
return '';
|
271 |
+
}
|
272 |
+
|
273 |
+
function updateAction() {
|
274 |
+
var f = document.forms[0], nl, i, h, v, s, head, html, l, tmp, addlink = true, ser;
|
275 |
+
|
276 |
+
head = doc.getElementsByTagName('head')[0];
|
277 |
+
|
278 |
+
// Fix scripts without a type
|
279 |
+
nl = doc.getElementsByTagName('script');
|
280 |
+
for (i=0; i<nl.length; i++) {
|
281 |
+
if (tinyMCEPopup.dom.getAttrib(nl[i], '_mce_type') == '')
|
282 |
+
nl[i].setAttribute('_mce_type', 'text/javascript');
|
283 |
+
}
|
284 |
+
|
285 |
+
// Get primary stylesheet
|
286 |
+
nl = doc.getElementsByTagName("link");
|
287 |
+
for (i=0; i<nl.length; i++) {
|
288 |
+
l = nl[i];
|
289 |
+
|
290 |
+
tmp = tinyMCEPopup.dom.getAttrib(l, 'media');
|
291 |
+
|
292 |
+
if (tinyMCEPopup.dom.getAttrib(l, '_mce_type') == "text/css" && (tmp == "" || tmp == "screen" || tmp == "all") && tinyMCEPopup.dom.getAttrib(l, 'rel') == "stylesheet") {
|
293 |
+
addlink = false;
|
294 |
+
|
295 |
+
if (f.stylesheet.value == '')
|
296 |
+
l.parentNode.removeChild(l);
|
297 |
+
else
|
298 |
+
l.setAttribute('_mce_href', f.stylesheet.value);
|
299 |
+
|
300 |
+
break;
|
301 |
+
}
|
302 |
+
}
|
303 |
+
|
304 |
+
// Add new link
|
305 |
+
if (f.stylesheet.value != '') {
|
306 |
+
l = doc.createElement('link');
|
307 |
+
|
308 |
+
l.setAttribute('type', 'text/css');
|
309 |
+
l.setAttribute('_mce_href', f.stylesheet.value);
|
310 |
+
l.setAttribute('rel', 'stylesheet');
|
311 |
+
|
312 |
+
head.appendChild(l);
|
313 |
+
}
|
314 |
+
|
315 |
+
setMeta(head, 'keywords', f.metakeywords.value);
|
316 |
+
setMeta(head, 'description', f.metadescription.value);
|
317 |
+
setMeta(head, 'author', f.metaauthor.value);
|
318 |
+
setMeta(head, 'copyright', f.metacopyright.value);
|
319 |
+
setMeta(head, 'robots', getSelectValue(f, 'metarobots'));
|
320 |
+
setMeta(head, 'Content-Type', getSelectValue(f, 'docencoding'));
|
321 |
+
|
322 |
+
doc.body.dir = getSelectValue(f, 'langdir');
|
323 |
+
doc.body.style.cssText = f.style.value;
|
324 |
+
|
325 |
+
doc.body.setAttribute('vLink', f.visited_color.value);
|
326 |
+
doc.body.setAttribute('link', f.link_color.value);
|
327 |
+
doc.body.setAttribute('text', f.textcolor.value);
|
328 |
+
doc.body.setAttribute('aLink', f.active_color.value);
|
329 |
+
|
330 |
+
doc.body.style.fontFamily = getSelectValue(f, 'fontface');
|
331 |
+
doc.body.style.fontSize = getSelectValue(f, 'fontsize');
|
332 |
+
doc.body.style.backgroundColor = f.bgcolor.value;
|
333 |
+
|
334 |
+
if (f.leftmargin.value != '')
|
335 |
+
doc.body.style.marginLeft = f.leftmargin.value + 'px';
|
336 |
+
|
337 |
+
if (f.rightmargin.value != '')
|
338 |
+
doc.body.style.marginRight = f.rightmargin.value + 'px';
|
339 |
+
|
340 |
+
if (f.bottommargin.value != '')
|
341 |
+
doc.body.style.marginBottom = f.bottommargin.value + 'px';
|
342 |
+
|
343 |
+
if (f.topmargin.value != '')
|
344 |
+
doc.body.style.marginTop = f.topmargin.value + 'px';
|
345 |
+
|
346 |
+
html = doc.getElementsByTagName('html')[0];
|
347 |
+
html.setAttribute('lang', f.langcode.value);
|
348 |
+
html.setAttribute('xml:lang', f.langcode.value);
|
349 |
+
|
350 |
+
if (f.bgimage.value != '')
|
351 |
+
doc.body.style.backgroundImage = "url('" + f.bgimage.value + "')";
|
352 |
+
else
|
353 |
+
doc.body.style.backgroundImage = '';
|
354 |
+
|
355 |
+
ser = tinyMCEPopup.editor.plugins.fullpage._createSerializer();
|
356 |
+
ser.setRules('-title,meta[http-equiv|name|content],base[href|target],link[href|rel|type|title|media],style[type],script[type|language|src],html[lang|xml::lang|xmlns],body[style|dir|vlink|link|text|alink],head');
|
357 |
+
|
358 |
+
h = ser.serialize(doc.documentElement);
|
359 |
+
h = h.substring(0, h.lastIndexOf('</body>'));
|
360 |
+
|
361 |
+
if (h.indexOf('<title>') == -1)
|
362 |
+
h = h.replace(/<head.*?>/, '$&\n' + '<title>' + tinyMCEPopup.dom.encode(f.metatitle.value) + '</title>');
|
363 |
+
else
|
364 |
+
h = h.replace(/<title>(.*?)<\/title>/, '<title>' + tinyMCEPopup.dom.encode(f.metatitle.value) + '</title>');
|
365 |
+
|
366 |
+
if ((v = getSelectValue(f, 'doctypes')) != '')
|
367 |
+
h = v + '\n' + h;
|
368 |
+
|
369 |
+
if (f.xml_pi.checked) {
|
370 |
+
s = '<?xml version="1.0"';
|
371 |
+
|
372 |
+
if ((v = getSelectValue(f, 'docencoding')) != '')
|
373 |
+
s += ' encoding="' + v + '"';
|
374 |
+
|
375 |
+
s += '?>\n';
|
376 |
+
h = s + h;
|
377 |
+
}
|
378 |
+
|
379 |
+
h = h.replace(/type=\"\-mce\-/gi, 'type="');
|
380 |
+
|
381 |
+
tinyMCEPopup.editor.plugins.fullpage.head = h;
|
382 |
+
tinyMCEPopup.editor.plugins.fullpage._setBodyAttribs(tinyMCEPopup.editor, {});
|
383 |
+
tinyMCEPopup.close();
|
384 |
+
}
|
385 |
+
|
386 |
+
function changedStyleField(field) {
|
387 |
+
}
|
388 |
+
|
389 |
+
function setMeta(he, k, v) {
|
390 |
+
var nl, i, m;
|
391 |
+
|
392 |
+
nl = he.getElementsByTagName('meta');
|
393 |
+
for (i=0; i<nl.length; i++) {
|
394 |
+
if (k == 'Content-Type' && tinyMCEPopup.dom.getAttrib(nl[i], 'http-equiv') == k) {
|
395 |
+
if (v == '')
|
396 |
+
nl[i].parentNode.removeChild(nl[i]);
|
397 |
+
else
|
398 |
+
nl[i].setAttribute('content', "text/html; charset=" + v);
|
399 |
+
|
400 |
+
return;
|
401 |
+
}
|
402 |
+
|
403 |
+
if (tinyMCEPopup.dom.getAttrib(nl[i], 'name') == k) {
|
404 |
+
if (v == '')
|
405 |
+
nl[i].parentNode.removeChild(nl[i]);
|
406 |
+
else
|
407 |
+
nl[i].setAttribute('content', v);
|
408 |
+
return;
|
409 |
+
}
|
410 |
+
}
|
411 |
+
|
412 |
+
if (v == '')
|
413 |
+
return;
|
414 |
+
|
415 |
+
m = doc.createElement('meta');
|
416 |
+
|
417 |
+
if (k == 'Content-Type')
|
418 |
+
m.httpEquiv = k;
|
419 |
+
else
|
420 |
+
m.setAttribute('name', k);
|
421 |
+
|
422 |
+
m.setAttribute('content', v);
|
423 |
+
he.appendChild(m);
|
424 |
+
}
|
425 |
+
|
426 |
+
function parseStyleElement(e) {
|
427 |
+
var v = e.innerHTML;
|
428 |
+
var p, i, r;
|
429 |
+
|
430 |
+
v = v.replace(/<!--/gi, '');
|
431 |
+
v = v.replace(/-->/gi, '');
|
432 |
+
v = v.replace(/[\n\r]/gi, '');
|
433 |
+
v = v.replace(/\s+/gi, ' ');
|
434 |
+
|
435 |
+
r = [];
|
436 |
+
p = v.split(/{|}/);
|
437 |
+
|
438 |
+
for (i=0; i<p.length; i+=2) {
|
439 |
+
if (p[i] != "")
|
440 |
+
r[r.length] = {rule : tinymce.trim(p[i]), data : tinyMCEPopup.dom.parseStyle(p[i+1])};
|
441 |
+
}
|
442 |
+
|
443 |
+
return r;
|
444 |
+
}
|
445 |
+
|
446 |
+
function serializeStyleElement(d) {
|
447 |
+
var i, s, st;
|
448 |
+
|
449 |
+
s = '<!--\n';
|
450 |
+
|
451 |
+
for (i=0; i<d.length; i++) {
|
452 |
+
s += d[i].rule + ' {\n';
|
453 |
+
|
454 |
+
st = tinyMCE.serializeStyle(d[i].data);
|
455 |
+
|
456 |
+
if (st != '')
|
457 |
+
st += ';';
|
458 |
+
|
459 |
+
s += st.replace(/;/g, ';\n');
|
460 |
+
s += '}\n';
|
461 |
+
|
462 |
+
if (i != d.length - 1)
|
463 |
+
s += '\n';
|
464 |
+
}
|
465 |
+
|
466 |
+
s += '\n-->';
|
467 |
+
|
468 |
+
return s;
|
469 |
+
}
|
470 |
+
|
471 |
+
tinyMCEPopup.onInit.add(init);
|
tinymce-plugins/3.3.x/fullpage/langs/en_dlg.js
ADDED
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
tinyMCE.addI18n('en.fullpage_dlg',{
|
2 |
+
title:"Document properties",
|
3 |
+
meta_tab:"General",
|
4 |
+
appearance_tab:"Appearance",
|
5 |
+
advanced_tab:"Advanced",
|
6 |
+
meta_props:"Meta information",
|
7 |
+
langprops:"Language and encoding",
|
8 |
+
meta_title:"Title",
|
9 |
+
meta_keywords:"Keywords",
|
10 |
+
meta_description:"Description",
|
11 |
+
meta_robots:"Robots",
|
12 |
+
doctypes:"Doctype",
|
13 |
+
langcode:"Language code",
|
14 |
+
langdir:"Language direction",
|
15 |
+
ltr:"Left to right",
|
16 |
+
rtl:"Right to left",
|
17 |
+
xml_pi:"XML declaration",
|
18 |
+
encoding:"Character encoding",
|
19 |
+
appearance_bgprops:"Background properties",
|
20 |
+
appearance_marginprops:"Body margins",
|
21 |
+
appearance_linkprops:"Link colors",
|
22 |
+
appearance_textprops:"Text properties",
|
23 |
+
bgcolor:"Background color",
|
24 |
+
bgimage:"Background image",
|
25 |
+
left_margin:"Left margin",
|
26 |
+
right_margin:"Right margin",
|
27 |
+
top_margin:"Top margin",
|
28 |
+
bottom_margin:"Bottom margin",
|
29 |
+
text_color:"Text color",
|
30 |
+
font_size:"Font size",
|
31 |
+
font_face:"Font face",
|
32 |
+
link_color:"Link color",
|
33 |
+
hover_color:"Hover color",
|
34 |
+
visited_color:"Visited color",
|
35 |
+
active_color:"Active color",
|
36 |
+
textcolor:"Color",
|
37 |
+
fontsize:"Font size",
|
38 |
+
fontface:"Font family",
|
39 |
+
meta_index_follow:"Index and follow the links",
|
40 |
+
meta_index_nofollow:"Index and don't follow the links",
|
41 |
+
meta_noindex_follow:"Do not index but follow the links",
|
42 |
+
meta_noindex_nofollow:"Do not index and don\'t follow the links",
|
43 |
+
appearance_style:"Stylesheet and style properties",
|
44 |
+
stylesheet:"Stylesheet",
|
45 |
+
style:"Style",
|
46 |
+
author:"Author",
|
47 |
+
copyright:"Copyright",
|
48 |
+
add:"Add new element",
|
49 |
+
remove:"Remove selected element",
|
50 |
+
moveup:"Move selected element up",
|
51 |
+
movedown:"Move selected element down",
|
52 |
+
head_elements:"Head elements",
|
53 |
+
info:"Information",
|
54 |
+
add_title:"Title element",
|
55 |
+
add_meta:"Meta element",
|
56 |
+
add_script:"Script element",
|
57 |
+
add_style:"Style element",
|
58 |
+
add_link:"Link element",
|
59 |
+
add_base:"Base element",
|
60 |
+
add_comment:"Comment node",
|
61 |
+
title_element:"Title element",
|
62 |
+
script_element:"Script element",
|
63 |
+
style_element:"Style element",
|
64 |
+
base_element:"Base element",
|
65 |
+
link_element:"Link element",
|
66 |
+
meta_element:"Meta element",
|
67 |
+
comment_element:"Comment",
|
68 |
+
src:"Src",
|
69 |
+
language:"Language",
|
70 |
+
href:"Href",
|
71 |
+
target:"Target",
|
72 |
+
type:"Type",
|
73 |
+
charset:"Charset",
|
74 |
+
defer:"Defer",
|
75 |
+
media:"Media",
|
76 |
+
properties:"Properties",
|
77 |
+
name:"Name",
|
78 |
+
value:"Value",
|
79 |
+
content:"Content",
|
80 |
+
rel:"Rel",
|
81 |
+
rev:"Rev",
|
82 |
+
hreflang:"Href lang",
|
83 |
+
general_props:"General",
|
84 |
+
advanced_props:"Advanced"
|
85 |
+
});
|
tinymce-plugins/3.4.x/fullpage/css/fullpage.css
ADDED
@@ -0,0 +1,143 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* Hide the advanced tab */
|
2 |
+
#advanced_tab {
|
3 |
+
display: none;
|
4 |
+
}
|
5 |
+
|
6 |
+
#metatitle, #metakeywords, #metadescription, #metaauthor, #metacopyright {
|
7 |
+
width: 280px;
|
8 |
+
}
|
9 |
+
|
10 |
+
#doctype, #docencoding {
|
11 |
+
width: 200px;
|
12 |
+
}
|
13 |
+
|
14 |
+
#langcode {
|
15 |
+
width: 30px;
|
16 |
+
}
|
17 |
+
|
18 |
+
#bgimage {
|
19 |
+
width: 220px;
|
20 |
+
}
|
21 |
+
|
22 |
+
#fontface {
|
23 |
+
width: 240px;
|
24 |
+
}
|
25 |
+
|
26 |
+
#leftmargin, #rightmargin, #topmargin, #bottommargin {
|
27 |
+
width: 50px;
|
28 |
+
}
|
29 |
+
|
30 |
+
.panel_wrapper div.current {
|
31 |
+
height: 400px;
|
32 |
+
}
|
33 |
+
|
34 |
+
#stylesheet, #style {
|
35 |
+
width: 240px;
|
36 |
+
}
|
37 |
+
|
38 |
+
#doctypes {
|
39 |
+
width: 200px;
|
40 |
+
}
|
41 |
+
|
42 |
+
/* Head list classes */
|
43 |
+
|
44 |
+
.headlistwrapper {
|
45 |
+
width: 100%;
|
46 |
+
}
|
47 |
+
|
48 |
+
.selected {
|
49 |
+
border: 1px solid #0A246A;
|
50 |
+
background-color: #B6BDD2;
|
51 |
+
}
|
52 |
+
|
53 |
+
.toolbar {
|
54 |
+
width: 100%;
|
55 |
+
}
|
56 |
+
|
57 |
+
#headlist {
|
58 |
+
width: 100%;
|
59 |
+
margin-top: 3px;
|
60 |
+
font-size: 11px;
|
61 |
+
}
|
62 |
+
|
63 |
+
#info, #title_element, #meta_element, #script_element, #style_element, #base_element, #link_element, #comment_element, #unknown_element {
|
64 |
+
display: none;
|
65 |
+
}
|
66 |
+
|
67 |
+
#addmenu {
|
68 |
+
position: absolute;
|
69 |
+
border: 1px solid gray;
|
70 |
+
display: none;
|
71 |
+
z-index: 100;
|
72 |
+
background-color: white;
|
73 |
+
}
|
74 |
+
|
75 |
+
#addmenu a {
|
76 |
+
display: block;
|
77 |
+
width: 100%;
|
78 |
+
line-height: 20px;
|
79 |
+
text-decoration: none;
|
80 |
+
background-color: white;
|
81 |
+
}
|
82 |
+
|
83 |
+
#addmenu a:hover {
|
84 |
+
background-color: #B6BDD2;
|
85 |
+
color: black;
|
86 |
+
}
|
87 |
+
|
88 |
+
#addmenu span {
|
89 |
+
padding-left: 10px;
|
90 |
+
padding-right: 10px;
|
91 |
+
}
|
92 |
+
|
93 |
+
#updateElementPanel {
|
94 |
+
display: none;
|
95 |
+
}
|
96 |
+
|
97 |
+
#script_element .panel_wrapper div.current {
|
98 |
+
height: 108px;
|
99 |
+
}
|
100 |
+
|
101 |
+
#style_element .panel_wrapper div.current {
|
102 |
+
height: 108px;
|
103 |
+
}
|
104 |
+
|
105 |
+
#link_element .panel_wrapper div.current {
|
106 |
+
height: 140px;
|
107 |
+
}
|
108 |
+
|
109 |
+
#element_script_value {
|
110 |
+
width: 100%;
|
111 |
+
height: 100px;
|
112 |
+
}
|
113 |
+
|
114 |
+
#element_comment_value {
|
115 |
+
width: 100%;
|
116 |
+
height: 120px;
|
117 |
+
}
|
118 |
+
|
119 |
+
#element_style_value {
|
120 |
+
width: 100%;
|
121 |
+
height: 100px;
|
122 |
+
}
|
123 |
+
|
124 |
+
#element_title, #element_script_src, #element_meta_name, #element_meta_content, #element_base_href, #element_link_href, #element_link_title {
|
125 |
+
width: 250px;
|
126 |
+
}
|
127 |
+
|
128 |
+
.updateElementButton {
|
129 |
+
margin-top: 3px;
|
130 |
+
}
|
131 |
+
|
132 |
+
/* MSIE specific styles */
|
133 |
+
|
134 |
+
* html .addbutton, * html .removebutton, * html .moveupbutton, * html .movedownbutton {
|
135 |
+
width: 22px;
|
136 |
+
height: 22px;
|
137 |
+
}
|
138 |
+
|
139 |
+
textarea {
|
140 |
+
height: 55px;
|
141 |
+
}
|
142 |
+
|
143 |
+
.panel_wrapper div.current {height:420px;}
|
tinymce-plugins/3.4.x/fullpage/editor_plugin.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
(function(){var b=tinymce.each,a=tinymce.html.Node;tinymce.create("tinymce.plugins.FullPagePlugin",{init:function(c,d){var e=this;e.editor=c;c.addCommand("mceFullPageProperties",function(){c.windowManager.open({file:d+"/fullpage.htm",width:430+parseInt(c.getLang("fullpage.delta_width",0)),height:495+parseInt(c.getLang("fullpage.delta_height",0)),inline:1},{plugin_url:d,data:e._htmlToData()})});c.addButton("fullpage",{title:"fullpage.desc",cmd:"mceFullPageProperties"});c.onBeforeSetContent.add(e._setContent,e);c.onGetContent.add(e._getContent,e)},getInfo:function(){return{longname:"Fullpage",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullpage",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_htmlToData:function(){var f=this._parseHeader(),h={},c,i,g,e=this.editor;function d(l,j){var k=l.attr(j);return k||""}h.fontface=e.getParam("fullpage_default_fontface","");h.fontsize=e.getParam("fullpage_default_fontsize","");i=f.firstChild;if(i.type==7){h.xml_pi=true;g=/encoding="([^"]+)"/.exec(i.value);if(g){h.docencoding=g[1]}}i=f.getAll("#doctype")[0];if(i){h.doctype="<!DOCTYPE"+i.value+">"}i=f.getAll("title")[0];if(i&&i.firstChild){h.metatitle=i.firstChild.value}b(f.getAll("meta"),function(m){var k=m.attr("name"),j=m.attr("http-equiv"),l;if(k){h["meta"+k.toLowerCase()]=m.attr("content")}else{if(j=="Content-Type"){l=/charset\s*=\s*(.*)\s*/gi.exec(m.attr("content"));if(l){h.docencoding=l[1]}}}});i=f.getAll("html")[0];if(i){h.langcode=d(i,"lang")||d(i,"xml:lang")}i=f.getAll("link")[0];if(i&&i.attr("rel")=="stylesheet"){h.stylesheet=i.attr("href")}i=f.getAll("body")[0];if(i){h.langdir=d(i,"dir");h.style=d(i,"style");h.visited_color=d(i,"vlink");h.link_color=d(i,"link");h.active_color=d(i,"alink")}return h},_dataToHtml:function(g){var f,d,h,j,k,e=this.editor.dom;function c(n,l,m){n.attr(l,m?m:undefined)}function i(l){if(d.firstChild){d.insert(l,d.firstChild)}else{d.append(l)}}f=this._parseHeader();d=f.getAll("head")[0];if(!d){j=f.getAll("html")[0];d=new a("head",1);if(j.firstChild){j.insert(d,j.firstChild,true)}else{j.append(d)}}j=f.firstChild;if(g.xml_pi){k='version="1.0"';if(g.docencoding){k+=' encoding="'+g.docencoding+'"'}if(j.type!=7){j=new a("xml",7);f.insert(j,f.firstChild,true)}j.value=k}else{if(j&&j.type==7){j.remove()}}j=f.getAll("#doctype")[0];if(g.doctype){if(!j){j=new a("#doctype",10);if(g.xml_pi){f.insert(j,f.firstChild)}else{i(j)}}j.value=g.doctype.substring(9,g.doctype.length-1)}else{if(j){j.remove()}}j=f.getAll("title")[0];if(g.metatitle){if(!j){j=new a("title",1);j.append(new a("#text",3)).value=g.metatitle;i(j)}}if(g.docencoding){j=null;b(f.getAll("meta"),function(l){if(l.attr("http-equiv")=="Content-Type"){j=l}});if(!j){j=new a("meta",1);j.attr("http-equiv","Content-Type");j.shortEnded=true;i(j)}j.attr("content","text/html; charset="+g.docencoding)}b("keywords,description,author,copyright,robots".split(","),function(m){var l=f.getAll("meta"),n,p,o=g["meta"+m];for(n=0;n<l.length;n++){p=l[n];if(p.attr("name")==m){if(o){p.attr("content",o)}else{p.remove()}return}}if(o){j=new a("meta",1);j.attr("name",m);j.attr("content",o);j.shortEnded=true;i(j)}});j=f.getAll("link")[0];if(j&&j.attr("rel")=="stylesheet"){if(g.stylesheet){j.attr("href",g.stylesheet)}else{j.remove()}}else{if(g.stylesheet){j=new a("link",1);j.attr({rel:"stylesheet",text:"text/css",href:g.stylesheet});j.shortEnded=true;i(j)}}j=f.getAll("body")[0];if(j){c(j,"dir",g.langdir);c(j,"style",g.style);c(j,"vlink",g.visited_color);c(j,"link",g.link_color);c(j,"alink",g.active_color);e.setAttribs(this.editor.getBody(),{style:g.style,dir:g.dir,vLink:g.visited_color,link:g.link_color,aLink:g.active_color})}j=f.getAll("html")[0];if(j){c(j,"lang",g.langcode);c(j,"xml:lang",g.langcode)}h=new tinymce.html.Serializer({validate:false,indent:true,apply_source_formatting:true,indent_before:"head,html,body,meta,title,script,link,style",indent_after:"head,html,body,meta,title,script,link,style"}).serialize(f);this.head=h.substring(0,h.indexOf("</body>"))},_parseHeader:function(){return new tinymce.html.DomParser({validate:false,root_name:"#document"}).parse(this.head)},_setContent:function(g,d){var m=this,i,c,h=d.content,f,l="",e=m.editor.dom,j;function k(n){return n.replace(/<\/?[A-Z]+/g,function(o){return o.toLowerCase()})}if(d.format=="raw"&&m.head){return}if(d.source_view&&g.getParam("fullpage_hide_in_source_view")){return}h=h.replace(/<(\/?)BODY/gi,"<$1body");i=h.indexOf("<body");if(i!=-1){i=h.indexOf(">",i);m.head=k(h.substring(0,i+1));c=h.indexOf("</body",i);if(c==-1){c=h.length}d.content=h.substring(i+1,c);m.foot=k(h.substring(c))}else{m.head=this._getDefaultHeader();m.foot="\n</body>\n</html>"}f=m._parseHeader();b(f.getAll("style"),function(n){if(n.firstChild){l+=n.firstChild.value}});j=f.getAll("body")[0];if(j){e.setAttribs(m.editor.getBody(),{style:j.attr("style")||"",dir:j.attr("dir")||"",vLink:j.attr("vlink")||"",link:j.attr("link")||"",aLink:j.attr("alink")||""})}if(l){e.add(m.editor.getDoc().getElementsByTagName("head")[0],"style",{id:"fullpage_styles"},l)}else{e.remove("fullpage_styles")}},_getDefaultHeader:function(){var f="",c=this.editor,e,d="";if(c.getParam("fullpage_default_xml_pi")){f+='<?xml version="1.0" encoding="'+c.getParam("fullpage_default_encoding","ISO-8859-1")+'" ?>\n'}f+=c.getParam("fullpage_default_doctype",'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">');f+="\n<html>\n<head>\n";if(e=c.getParam("fullpage_default_title")){f+="<title>"+e+"</title>\n"}if(e=c.getParam("fullpage_default_encoding")){f+='<meta http-equiv="Content-Type" content="text/html; charset='+e+'" />\n'}if(e=c.getParam("fullpage_default_font_family")){d+="font-family: "+e+";"}if(e=c.getParam("fullpage_default_font_size")){d+="font-size: "+e+";"}if(e=c.getParam("fullpage_default_text_color")){d+="color: "+e+";"}f+="</head>\n<body"+(d?' style="'+d+'"':"")+">\n";return f},_getContent:function(d,e){var c=this;if(!e.source_view||!d.getParam("fullpage_hide_in_source_view")){e.content=tinymce.trim(c.head)+"\n"+tinymce.trim(e.content)+"\n"+tinymce.trim(c.foot)}}});tinymce.PluginManager.add("fullpage",tinymce.plugins.FullPagePlugin)})();
|
tinymce-plugins/3.4.x/fullpage/editor_plugin_src.js
ADDED
@@ -0,0 +1,399 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* editor_plugin_src.js
|
3 |
+
*
|
4 |
+
* Copyright 2009, Moxiecode Systems AB
|
5 |
+
* Released under LGPL License.
|
6 |
+
*
|
7 |
+
* License: http://tinymce.moxiecode.com/license
|
8 |
+
* Contributing: http://tinymce.moxiecode.com/contributing
|
9 |
+
*/
|
10 |
+
|
11 |
+
(function() {
|
12 |
+
var each = tinymce.each, Node = tinymce.html.Node;
|
13 |
+
|
14 |
+
tinymce.create('tinymce.plugins.FullPagePlugin', {
|
15 |
+
init : function(ed, url) {
|
16 |
+
var t = this;
|
17 |
+
|
18 |
+
t.editor = ed;
|
19 |
+
|
20 |
+
// Register commands
|
21 |
+
ed.addCommand('mceFullPageProperties', function() {
|
22 |
+
ed.windowManager.open({
|
23 |
+
file : url + '/fullpage.htm',
|
24 |
+
width : 430 + parseInt(ed.getLang('fullpage.delta_width', 0)),
|
25 |
+
height : 495 + parseInt(ed.getLang('fullpage.delta_height', 0)),
|
26 |
+
inline : 1
|
27 |
+
}, {
|
28 |
+
plugin_url : url,
|
29 |
+
data : t._htmlToData()
|
30 |
+
});
|
31 |
+
});
|
32 |
+
|
33 |
+
// Register buttons
|
34 |
+
ed.addButton('fullpage', {title : 'fullpage.desc', cmd : 'mceFullPageProperties'});
|
35 |
+
|
36 |
+
ed.onBeforeSetContent.add(t._setContent, t);
|
37 |
+
ed.onGetContent.add(t._getContent, t);
|
38 |
+
},
|
39 |
+
|
40 |
+
getInfo : function() {
|
41 |
+
return {
|
42 |
+
longname : 'Fullpage',
|
43 |
+
author : 'Moxiecode Systems AB',
|
44 |
+
authorurl : 'http://tinymce.moxiecode.com',
|
45 |
+
infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullpage',
|
46 |
+
version : tinymce.majorVersion + "." + tinymce.minorVersion
|
47 |
+
};
|
48 |
+
},
|
49 |
+
|
50 |
+
// Private plugin internal methods
|
51 |
+
|
52 |
+
_htmlToData : function() {
|
53 |
+
var headerFragment = this._parseHeader(), data = {}, nodes, elm, matches, editor = this.editor;
|
54 |
+
|
55 |
+
function getAttr(elm, name) {
|
56 |
+
var value = elm.attr(name);
|
57 |
+
|
58 |
+
return value || '';
|
59 |
+
};
|
60 |
+
|
61 |
+
// Default some values
|
62 |
+
data.fontface = editor.getParam("fullpage_default_fontface", "");
|
63 |
+
data.fontsize = editor.getParam("fullpage_default_fontsize", "");
|
64 |
+
|
65 |
+
// Parse XML PI
|
66 |
+
elm = headerFragment.firstChild;
|
67 |
+
if (elm.type == 7) {
|
68 |
+
data.xml_pi = true;
|
69 |
+
matches = /encoding="([^"]+)"/.exec(elm.value);
|
70 |
+
if (matches)
|
71 |
+
data.docencoding = matches[1];
|
72 |
+
}
|
73 |
+
|
74 |
+
// Parse doctype
|
75 |
+
elm = headerFragment.getAll('#doctype')[0];
|
76 |
+
if (elm)
|
77 |
+
data.doctype = '<!DOCTYPE' + elm.value + ">";
|
78 |
+
|
79 |
+
// Parse title element
|
80 |
+
elm = headerFragment.getAll('title')[0];
|
81 |
+
if (elm && elm.firstChild) {
|
82 |
+
data.metatitle = elm.firstChild.value;
|
83 |
+
}
|
84 |
+
|
85 |
+
// Parse meta elements
|
86 |
+
each(headerFragment.getAll('meta'), function(meta) {
|
87 |
+
var name = meta.attr('name'), httpEquiv = meta.attr('http-equiv'), matches;
|
88 |
+
|
89 |
+
if (name)
|
90 |
+
data['meta' + name.toLowerCase()] = meta.attr('content');
|
91 |
+
else if (httpEquiv == "Content-Type") {
|
92 |
+
matches = /charset\s*=\s*(.*)\s*/gi.exec(meta.attr('content'));
|
93 |
+
|
94 |
+
if (matches)
|
95 |
+
data.docencoding = matches[1];
|
96 |
+
}
|
97 |
+
});
|
98 |
+
|
99 |
+
// Parse html attribs
|
100 |
+
elm = headerFragment.getAll('html')[0];
|
101 |
+
if (elm)
|
102 |
+
data.langcode = getAttr(elm, 'lang') || getAttr(elm, 'xml:lang');
|
103 |
+
|
104 |
+
// Parse stylesheet
|
105 |
+
elm = headerFragment.getAll('link')[0];
|
106 |
+
if (elm && elm.attr('rel') == 'stylesheet')
|
107 |
+
data.stylesheet = elm.attr('href');
|
108 |
+
|
109 |
+
// Parse body parts
|
110 |
+
elm = headerFragment.getAll('body')[0];
|
111 |
+
if (elm) {
|
112 |
+
data.langdir = getAttr(elm, 'dir');
|
113 |
+
data.style = getAttr(elm, 'style');
|
114 |
+
data.visited_color = getAttr(elm, 'vlink');
|
115 |
+
data.link_color = getAttr(elm, 'link');
|
116 |
+
data.active_color = getAttr(elm, 'alink');
|
117 |
+
}
|
118 |
+
|
119 |
+
return data;
|
120 |
+
},
|
121 |
+
|
122 |
+
_dataToHtml : function(data) {
|
123 |
+
var headerFragment, headElement, html, elm, value, dom = this.editor.dom;
|
124 |
+
|
125 |
+
function setAttr(elm, name, value) {
|
126 |
+
elm.attr(name, value ? value : undefined);
|
127 |
+
};
|
128 |
+
|
129 |
+
function addHeadNode(node) {
|
130 |
+
if (headElement.firstChild)
|
131 |
+
headElement.insert(node, headElement.firstChild);
|
132 |
+
else
|
133 |
+
headElement.append(node);
|
134 |
+
};
|
135 |
+
|
136 |
+
headerFragment = this._parseHeader();
|
137 |
+
headElement = headerFragment.getAll('head')[0];
|
138 |
+
if (!headElement) {
|
139 |
+
elm = headerFragment.getAll('html')[0];
|
140 |
+
headElement = new Node('head', 1);
|
141 |
+
|
142 |
+
if (elm.firstChild)
|
143 |
+
elm.insert(headElement, elm.firstChild, true);
|
144 |
+
else
|
145 |
+
elm.append(headElement);
|
146 |
+
}
|
147 |
+
|
148 |
+
// Add/update/remove XML-PI
|
149 |
+
elm = headerFragment.firstChild;
|
150 |
+
if (data.xml_pi) {
|
151 |
+
value = 'version="1.0"';
|
152 |
+
|
153 |
+
if (data.docencoding)
|
154 |
+
value += ' encoding="' + data.docencoding + '"';
|
155 |
+
|
156 |
+
if (elm.type != 7) {
|
157 |
+
elm = new Node('xml', 7);
|
158 |
+
headerFragment.insert(elm, headerFragment.firstChild, true);
|
159 |
+
}
|
160 |
+
|
161 |
+
elm.value = value;
|
162 |
+
} else if (elm && elm.type == 7)
|
163 |
+
elm.remove();
|
164 |
+
|
165 |
+
// Add/update/remove doctype
|
166 |
+
elm = headerFragment.getAll('#doctype')[0];
|
167 |
+
if (data.doctype) {
|
168 |
+
if (!elm) {
|
169 |
+
elm = new Node('#doctype', 10);
|
170 |
+
|
171 |
+
if (data.xml_pi)
|
172 |
+
headerFragment.insert(elm, headerFragment.firstChild);
|
173 |
+
else
|
174 |
+
addHeadNode(elm);
|
175 |
+
}
|
176 |
+
|
177 |
+
elm.value = data.doctype.substring(9, data.doctype.length - 1);
|
178 |
+
} else if (elm)
|
179 |
+
elm.remove();
|
180 |
+
|
181 |
+
// Add/update/remove title
|
182 |
+
elm = headerFragment.getAll('title')[0];
|
183 |
+
if (data.metatitle) {
|
184 |
+
if (!elm) {
|
185 |
+
elm = new Node('title', 1);
|
186 |
+
elm.append(new Node('#text', 3)).value = data.metatitle;
|
187 |
+
addHeadNode(elm);
|
188 |
+
}
|
189 |
+
}
|
190 |
+
|
191 |
+
// Add meta encoding
|
192 |
+
if (data.docencoding) {
|
193 |
+
elm = null;
|
194 |
+
each(headerFragment.getAll('meta'), function(meta) {
|
195 |
+
if (meta.attr('http-equiv') == 'Content-Type')
|
196 |
+
elm = meta;
|
197 |
+
});
|
198 |
+
|
199 |
+
if (!elm) {
|
200 |
+
elm = new Node('meta', 1);
|
201 |
+
elm.attr('http-equiv', 'Content-Type');
|
202 |
+
elm.shortEnded = true;
|
203 |
+
addHeadNode(elm);
|
204 |
+
}
|
205 |
+
|
206 |
+
elm.attr('content', 'text/html; charset=' + data.docencoding);
|
207 |
+
}
|
208 |
+
|
209 |
+
// Add/update/remove meta
|
210 |
+
each('keywords,description,author,copyright,robots'.split(','), function(name) {
|
211 |
+
var nodes = headerFragment.getAll('meta'), i, meta, value = data['meta' + name];
|
212 |
+
|
213 |
+
for (i = 0; i < nodes.length; i++) {
|
214 |
+
meta = nodes[i];
|
215 |
+
|
216 |
+
if (meta.attr('name') == name) {
|
217 |
+
if (value)
|
218 |
+
meta.attr('content', value);
|
219 |
+
else
|
220 |
+
meta.remove();
|
221 |
+
|
222 |
+
return;
|
223 |
+
}
|
224 |
+
}
|
225 |
+
|
226 |
+
if (value) {
|
227 |
+
elm = new Node('meta', 1);
|
228 |
+
elm.attr('name', name);
|
229 |
+
elm.attr('content', value);
|
230 |
+
elm.shortEnded = true;
|
231 |
+
|
232 |
+
addHeadNode(elm);
|
233 |
+
}
|
234 |
+
});
|
235 |
+
|
236 |
+
// Add/update/delete link
|
237 |
+
elm = headerFragment.getAll('link')[0];
|
238 |
+
if (elm && elm.attr('rel') == 'stylesheet') {
|
239 |
+
if (data.stylesheet)
|
240 |
+
elm.attr('href', data.stylesheet);
|
241 |
+
else
|
242 |
+
elm.remove();
|
243 |
+
} else if (data.stylesheet) {
|
244 |
+
elm = new Node('link', 1);
|
245 |
+
elm.attr({
|
246 |
+
rel : 'stylesheet',
|
247 |
+
text : 'text/css',
|
248 |
+
href : data.stylesheet
|
249 |
+
});
|
250 |
+
elm.shortEnded = true;
|
251 |
+
|
252 |
+
addHeadNode(elm);
|
253 |
+
}
|
254 |
+
|
255 |
+
// Update body attributes
|
256 |
+
elm = headerFragment.getAll('body')[0];
|
257 |
+
if (elm) {
|
258 |
+
setAttr(elm, 'dir', data.langdir);
|
259 |
+
setAttr(elm, 'style', data.style);
|
260 |
+
setAttr(elm, 'vlink', data.visited_color);
|
261 |
+
setAttr(elm, 'link', data.link_color);
|
262 |
+
setAttr(elm, 'alink', data.active_color);
|
263 |
+
|
264 |
+
// Update iframe body as well
|
265 |
+
dom.setAttribs(this.editor.getBody(), {
|
266 |
+
style : data.style,
|
267 |
+
dir : data.dir,
|
268 |
+
vLink : data.visited_color,
|
269 |
+
link : data.link_color,
|
270 |
+
aLink : data.active_color
|
271 |
+
});
|
272 |
+
}
|
273 |
+
|
274 |
+
// Set html attributes
|
275 |
+
elm = headerFragment.getAll('html')[0];
|
276 |
+
if (elm) {
|
277 |
+
setAttr(elm, 'lang', data.langcode);
|
278 |
+
setAttr(elm, 'xml:lang', data.langcode);
|
279 |
+
}
|
280 |
+
|
281 |
+
// Serialize header fragment and crop away body part
|
282 |
+
html = new tinymce.html.Serializer({
|
283 |
+
validate: false,
|
284 |
+
indent: true,
|
285 |
+
apply_source_formatting : true,
|
286 |
+
indent_before: 'head,html,body,meta,title,script,link,style',
|
287 |
+
indent_after: 'head,html,body,meta,title,script,link,style'
|
288 |
+
}).serialize(headerFragment);
|
289 |
+
|
290 |
+
this.head = html.substring(0, html.indexOf('</body>'));
|
291 |
+
},
|
292 |
+
|
293 |
+
_parseHeader : function() {
|
294 |
+
// Parse the contents with a DOM parser
|
295 |
+
return new tinymce.html.DomParser({
|
296 |
+
validate: false,
|
297 |
+
root_name: '#document'
|
298 |
+
}).parse(this.head);
|
299 |
+
},
|
300 |
+
|
301 |
+
_setContent : function(ed, o) {
|
302 |
+
var self = this, startPos, endPos, content = o.content, headerFragment, styles = '', dom = self.editor.dom, elm;
|
303 |
+
|
304 |
+
function low(s) {
|
305 |
+
return s.replace(/<\/?[A-Z]+/g, function(a) {
|
306 |
+
return a.toLowerCase();
|
307 |
+
})
|
308 |
+
};
|
309 |
+
|
310 |
+
// Ignore raw updated if we already have a head, this will fix issues with undo/redo keeping the head/foot separate
|
311 |
+
if (o.format == 'raw' && self.head)
|
312 |
+
return;
|
313 |
+
|
314 |
+
if (o.source_view && ed.getParam('fullpage_hide_in_source_view'))
|
315 |
+
return;
|
316 |
+
|
317 |
+
// Parse out head, body and footer
|
318 |
+
content = content.replace(/<(\/?)BODY/gi, '<$1body');
|
319 |
+
startPos = content.indexOf('<body');
|
320 |
+
|
321 |
+
if (startPos != -1) {
|
322 |
+
startPos = content.indexOf('>', startPos);
|
323 |
+
self.head = low(content.substring(0, startPos + 1));
|
324 |
+
|
325 |
+
endPos = content.indexOf('</body', startPos);
|
326 |
+
if (endPos == -1)
|
327 |
+
endPos = content.length;
|
328 |
+
|
329 |
+
o.content = content.substring(startPos + 1, endPos);
|
330 |
+
self.foot = low(content.substring(endPos));
|
331 |
+
} else {
|
332 |
+
self.head = this._getDefaultHeader();
|
333 |
+
self.foot = '\n</body>\n</html>';
|
334 |
+
}
|
335 |
+
|
336 |
+
// Parse header and update iframe
|
337 |
+
headerFragment = self._parseHeader();
|
338 |
+
each(headerFragment.getAll('style'), function(node) {
|
339 |
+
if (node.firstChild)
|
340 |
+
styles += node.firstChild.value;
|
341 |
+
});
|
342 |
+
|
343 |
+
elm = headerFragment.getAll('body')[0];
|
344 |
+
if (elm) {
|
345 |
+
dom.setAttribs(self.editor.getBody(), {
|
346 |
+
style : elm.attr('style') || '',
|
347 |
+
dir : elm.attr('dir') || '',
|
348 |
+
vLink : elm.attr('vlink') || '',
|
349 |
+
link : elm.attr('link') || '',
|
350 |
+
aLink : elm.attr('alink') || ''
|
351 |
+
});
|
352 |
+
}
|
353 |
+
|
354 |
+
if (styles)
|
355 |
+
dom.add(self.editor.getDoc().getElementsByTagName('head')[0], 'style', {id : 'fullpage_styles'}, styles);
|
356 |
+
else
|
357 |
+
dom.remove('fullpage_styles');
|
358 |
+
},
|
359 |
+
|
360 |
+
_getDefaultHeader : function() {
|
361 |
+
var header = '', editor = this.editor, value, styles = '';
|
362 |
+
|
363 |
+
if (editor.getParam('fullpage_default_xml_pi'))
|
364 |
+
header += '<?xml version="1.0" encoding="' + editor.getParam('fullpage_default_encoding', 'ISO-8859-1') + '" ?>\n';
|
365 |
+
|
366 |
+
header += editor.getParam('fullpage_default_doctype', '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">');
|
367 |
+
header += '\n<html>\n<head>\n';
|
368 |
+
|
369 |
+
if (value = editor.getParam('fullpage_default_title'))
|
370 |
+
header += '<title>' + value + '</title>\n';
|
371 |
+
|
372 |
+
if (value = editor.getParam('fullpage_default_encoding'))
|
373 |
+
header += '<meta http-equiv="Content-Type" content="text/html; charset=' + value + '" />\n';
|
374 |
+
|
375 |
+
if (value = editor.getParam('fullpage_default_font_family'))
|
376 |
+
styles += 'font-family: ' + value + ';';
|
377 |
+
|
378 |
+
if (value = editor.getParam('fullpage_default_font_size'))
|
379 |
+
styles += 'font-size: ' + value + ';';
|
380 |
+
|
381 |
+
if (value = editor.getParam('fullpage_default_text_color'))
|
382 |
+
styles += 'color: ' + value + ';';
|
383 |
+
|
384 |
+
header += '</head>\n<body' + (styles ? ' style="' + styles + '"' : '') + '>\n';
|
385 |
+
|
386 |
+
return header;
|
387 |
+
},
|
388 |
+
|
389 |
+
_getContent : function(ed, o) {
|
390 |
+
var self = this;
|
391 |
+
|
392 |
+
if (!o.source_view || !ed.getParam('fullpage_hide_in_source_view'))
|
393 |
+
o.content = tinymce.trim(self.head) + '\n' + tinymce.trim(o.content) + '\n' + tinymce.trim(self.foot);
|
394 |
+
}
|
395 |
+
});
|
396 |
+
|
397 |
+
// Register plugin
|
398 |
+
tinymce.PluginManager.add('fullpage', tinymce.plugins.FullPagePlugin);
|
399 |
+
})();
|
tinymce-plugins/3.4.x/fullpage/fullpage.htm
ADDED
@@ -0,0 +1,259 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
2 |
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
3 |
+
<head>
|
4 |
+
<title>{#fullpage_dlg.title}</title>
|
5 |
+
<script type="text/javascript" src="../../tiny_mce_popup.js"></script>
|
6 |
+
<script type="text/javascript" src="../../utils/mctabs.js"></script>
|
7 |
+
<script type="text/javascript" src="../../utils/form_utils.js"></script>
|
8 |
+
<script type="text/javascript" src="js/fullpage.js"></script>
|
9 |
+
<link href="css/fullpage.css" rel="stylesheet" type="text/css" />
|
10 |
+
</head>
|
11 |
+
<body id="fullpage" style="display: none">
|
12 |
+
<form onsubmit="FullPageDialog.update();return false;" name="fullpage" action="#">
|
13 |
+
<div class="tabs">
|
14 |
+
<ul>
|
15 |
+
<li id="meta_tab" class="current"><span><a href="javascript:mcTabs.displayTab('meta_tab','meta_panel');" onmousedown="return false;">{#fullpage_dlg.meta_tab}</a></span></li>
|
16 |
+
<li id="appearance_tab"><span><a href="javascript:mcTabs.displayTab('appearance_tab','appearance_panel');" onmousedown="return false;">{#fullpage_dlg.appearance_tab}</a></span></li>
|
17 |
+
</ul>
|
18 |
+
</div>
|
19 |
+
|
20 |
+
<div class="panel_wrapper">
|
21 |
+
<div id="meta_panel" class="panel current">
|
22 |
+
<fieldset>
|
23 |
+
<legend>{#fullpage_dlg.meta_props}</legend>
|
24 |
+
|
25 |
+
<table border="0" cellpadding="4" cellspacing="0">
|
26 |
+
<tr>
|
27 |
+
<td class="nowrap"><label for="metatitle">{#fullpage_dlg.meta_title}</label> </td>
|
28 |
+
<td><input type="text" id="metatitle" name="metatitle" value="" class="mceFocus" /></td>
|
29 |
+
</tr>
|
30 |
+
<tr>
|
31 |
+
<td class="nowrap"><label for="metakeywords">{#fullpage_dlg.meta_keywords}</label> </td>
|
32 |
+
<td><textarea id="metakeywords" name="metakeywords" rows="4"></textarea></td>
|
33 |
+
</tr>
|
34 |
+
<tr>
|
35 |
+
<td class="nowrap"><label for="metadescription">{#fullpage_dlg.meta_description}</label> </td>
|
36 |
+
<td><textarea id="metadescription" name="metadescription" rows="4"></textarea></td>
|
37 |
+
</tr>
|
38 |
+
<tr>
|
39 |
+
<td class="nowrap"><label for="metaauthor">{#fullpage_dlg.author}</label> </td>
|
40 |
+
<td><input type="text" id="metaauthor" name="metaauthor" value="" /></td>
|
41 |
+
</tr>
|
42 |
+
<tr>
|
43 |
+
<td class="nowrap"><label for="metacopyright">{#fullpage_dlg.copyright}</label> </td>
|
44 |
+
<td><input type="text" id="metacopyright" name="metacopyright" value="" /></td>
|
45 |
+
</tr>
|
46 |
+
<tr>
|
47 |
+
<td class="nowrap"><label for="metarobots">{#fullpage_dlg.meta_robots}</label> </td>
|
48 |
+
<td>
|
49 |
+
<select id="metarobots" name="metarobots">
|
50 |
+
<option value="">{#not_set}</option>
|
51 |
+
<option value="index,follow">{#fullpage_dlg.meta_index_follow}</option>
|
52 |
+
<option value="index,nofollow">{#fullpage_dlg.meta_index_nofollow}</option>
|
53 |
+
<option value="noindex,follow">{#fullpage_dlg.meta_noindex_follow}</option>
|
54 |
+
<option value="noindex,nofollow">{#fullpage_dlg.meta_noindex_nofollow}</option>
|
55 |
+
</select>
|
56 |
+
</td>
|
57 |
+
</tr>
|
58 |
+
</table>
|
59 |
+
</fieldset>
|
60 |
+
|
61 |
+
<fieldset>
|
62 |
+
<legend>{#fullpage_dlg.langprops}</legend>
|
63 |
+
|
64 |
+
<table border="0" cellpadding="4" cellspacing="0">
|
65 |
+
<tr>
|
66 |
+
<td class="column1"><label for="docencoding">{#fullpage_dlg.encoding}</label></td>
|
67 |
+
<td>
|
68 |
+
<select id="docencoding" name="docencoding">
|
69 |
+
<option value="">{#not_set}</option>
|
70 |
+
</select>
|
71 |
+
</td>
|
72 |
+
</tr>
|
73 |
+
<tr>
|
74 |
+
<td class="nowrap"><label for="doctype">{#fullpage_dlg.doctypes}</label> </td>
|
75 |
+
<td>
|
76 |
+
<select id="doctype" name="doctype">
|
77 |
+
<option value="">{#not_set}</option>
|
78 |
+
</select>
|
79 |
+
</td>
|
80 |
+
</tr>
|
81 |
+
<tr>
|
82 |
+
<td class="nowrap"><label for="langcode">{#fullpage_dlg.langcode}</label> </td>
|
83 |
+
<td><input type="text" id="langcode" name="langcode" value="" /></td>
|
84 |
+
</tr>
|
85 |
+
<tr>
|
86 |
+
<td class="column1"><label for="langdir">{#fullpage_dlg.langdir}</label></td>
|
87 |
+
<td>
|
88 |
+
<select id="langdir" name="langdir">
|
89 |
+
<option value="">{#not_set}</option>
|
90 |
+
<option value="ltr">{#fullpage_dlg.ltr}</option>
|
91 |
+
<option value="rtl">{#fullpage_dlg.rtl}</option>
|
92 |
+
</select>
|
93 |
+
</td>
|
94 |
+
</tr>
|
95 |
+
<tr>
|
96 |
+
<td class="nowrap"><label for="xml_pi">{#fullpage_dlg.xml_pi}</label> </td>
|
97 |
+
<td><input type="checkbox" id="xml_pi" name="xml_pi" class="checkbox" /></td>
|
98 |
+
</tr>
|
99 |
+
</table>
|
100 |
+
</fieldset>
|
101 |
+
</div>
|
102 |
+
|
103 |
+
<div id="appearance_panel" class="panel">
|
104 |
+
<fieldset>
|
105 |
+
<legend>{#fullpage_dlg.appearance_textprops}</legend>
|
106 |
+
|
107 |
+
<table border="0" cellpadding="4" cellspacing="0">
|
108 |
+
<tr>
|
109 |
+
<td class="column1"><label for="fontface">{#fullpage_dlg.fontface}</label></td>
|
110 |
+
<td>
|
111 |
+
<select id="fontface" name="fontface" onchange="FullPageDialog.changedStyleProp();">
|
112 |
+
<option value="">{#not_set}</option>
|
113 |
+
</select>
|
114 |
+
</td>
|
115 |
+
</tr>
|
116 |
+
|
117 |
+
<tr>
|
118 |
+
<td class="column1"><label for="fontsize">{#fullpage_dlg.fontsize}</label></td>
|
119 |
+
<td>
|
120 |
+
<select id="fontsize" name="fontsize" onchange="FullPageDialog.changedStyleProp();">
|
121 |
+
<option value="">{#not_set}</option>
|
122 |
+
</select>
|
123 |
+
</td>
|
124 |
+
</tr>
|
125 |
+
|
126 |
+
<tr>
|
127 |
+
<td class="column1"><label for="textcolor">{#fullpage_dlg.textcolor}</label></td>
|
128 |
+
<td>
|
129 |
+
<table border="0" cellpadding="0" cellspacing="0">
|
130 |
+
<tr>
|
131 |
+
<td><input id="textcolor" name="textcolor" type="text" value="" size="9" onchange="updateColor('textcolor_pick','textcolor');FullPageDialog.changedStyleProp();" /></td>
|
132 |
+
<td id="textcolor_pickcontainer"> </td>
|
133 |
+
</tr>
|
134 |
+
</table>
|
135 |
+
</td>
|
136 |
+
</tr>
|
137 |
+
</table>
|
138 |
+
</fieldset>
|
139 |
+
|
140 |
+
<fieldset>
|
141 |
+
<legend>{#fullpage_dlg.appearance_bgprops}</legend>
|
142 |
+
|
143 |
+
<table border="0" cellpadding="4" cellspacing="0">
|
144 |
+
<tr>
|
145 |
+
<td class="column1"><label for="bgimage">{#fullpage_dlg.bgimage}</label></td>
|
146 |
+
<td>
|
147 |
+
<table border="0" cellpadding="0" cellspacing="0">
|
148 |
+
<tr>
|
149 |
+
<td><input id="bgimage" name="bgimage" type="text" value="" onchange="FullPageDialog.changedStyleProp();" /></td>
|
150 |
+
<td id="bgimage_pickcontainer"> </td>
|
151 |
+
</tr>
|
152 |
+
</table>
|
153 |
+
</td>
|
154 |
+
</tr>
|
155 |
+
<tr>
|
156 |
+
<td class="column1"><label for="bgcolor">{#fullpage_dlg.bgcolor}</label></td>
|
157 |
+
<td>
|
158 |
+
<table border="0" cellpadding="0" cellspacing="0">
|
159 |
+
<tr>
|
160 |
+
<td><input id="bgcolor" name="bgcolor" type="text" value="" size="9" onchange="updateColor('bgcolor_pick','bgcolor');FullPageDialog.changedStyleProp();" /></td>
|
161 |
+
<td id="bgcolor_pickcontainer"> </td>
|
162 |
+
</tr>
|
163 |
+
</table>
|
164 |
+
</td>
|
165 |
+
</tr>
|
166 |
+
</table>
|
167 |
+
</fieldset>
|
168 |
+
|
169 |
+
<fieldset>
|
170 |
+
<legend>{#fullpage_dlg.appearance_marginprops}</legend>
|
171 |
+
|
172 |
+
<table border="0" cellpadding="4" cellspacing="0">
|
173 |
+
<tr>
|
174 |
+
<td class="column1"><label for="leftmargin">{#fullpage_dlg.left_margin}</label></td>
|
175 |
+
<td><input id="leftmargin" name="leftmargin" type="text" value="" onchange="FullPageDialog.changedStyleProp();" /></td>
|
176 |
+
<td class="column1"><label for="rightmargin">{#fullpage_dlg.right_margin}</label></td>
|
177 |
+
<td><input id="rightmargin" name="rightmargin" type="text" value="" onchange="FullPageDialog.changedStyleProp();" /></td>
|
178 |
+
</tr>
|
179 |
+
<tr>
|
180 |
+
<td class="column1"><label for="topmargin">{#fullpage_dlg.top_margin}</label></td>
|
181 |
+
<td><input id="topmargin" name="topmargin" type="text" value="" onchange="FullPageDialog.changedStyleProp();" /></td>
|
182 |
+
<td class="column1"><label for="bottommargin">{#fullpage_dlg.bottom_margin}</label></td>
|
183 |
+
<td><input id="bottommargin" name="bottommargin" type="text" value="" onchange="FullPageDialog.changedStyleProp();" /></td>
|
184 |
+
</tr>
|
185 |
+
</table>
|
186 |
+
</fieldset>
|
187 |
+
|
188 |
+
<fieldset>
|
189 |
+
<legend>{#fullpage_dlg.appearance_linkprops}</legend>
|
190 |
+
|
191 |
+
<table border="0" cellpadding="4" cellspacing="0">
|
192 |
+
<tr>
|
193 |
+
<td class="column1"><label for="link_color">{#fullpage_dlg.link_color}</label></td>
|
194 |
+
<td>
|
195 |
+
<table border="0" cellpadding="0" cellspacing="0">
|
196 |
+
<tr>
|
197 |
+
<td><input id="link_color" name="link_color" type="text" value="" size="9" onchange="updateColor('link_color_pick','link_color');FullPageDialog.changedStyleProp();" /></td>
|
198 |
+
<td id="link_color_pickcontainer"> </td>
|
199 |
+
</tr>
|
200 |
+
</table>
|
201 |
+
</td>
|
202 |
+
|
203 |
+
<td class="column1"><label for="visited_color">{#fullpage_dlg.visited_color}</label></td>
|
204 |
+
<td>
|
205 |
+
<table border="0" cellpadding="0" cellspacing="0">
|
206 |
+
<tr>
|
207 |
+
<td><input id="visited_color" name="visited_color" type="text" value="" size="9" onchange="updateColor('visited_color_pick','visited_color');FullPageDialog.changedStyleProp();" /></td>
|
208 |
+
<td id="visited_color_pickcontainer"> </td>
|
209 |
+
</tr>
|
210 |
+
</table>
|
211 |
+
</td>
|
212 |
+
</tr>
|
213 |
+
|
214 |
+
<tr>
|
215 |
+
<td class="column1"><label for="active_color">{#fullpage_dlg.active_color}</label></td>
|
216 |
+
<td>
|
217 |
+
<table border="0" cellpadding="0" cellspacing="0">
|
218 |
+
<tr>
|
219 |
+
<td><input id="active_color" name="active_color" type="text" value="" size="9" onchange="updateColor('active_color_pick','active_color');FullPageDialog.changedStyleProp();" /></td>
|
220 |
+
<td id="active_color_pickcontainer"> </td>
|
221 |
+
</tr>
|
222 |
+
</table>
|
223 |
+
</td>
|
224 |
+
|
225 |
+
<td> </td>
|
226 |
+
<td> </td>
|
227 |
+
</tr>
|
228 |
+
</table>
|
229 |
+
</fieldset>
|
230 |
+
|
231 |
+
<fieldset>
|
232 |
+
<legend>{#fullpage_dlg.appearance_style}</legend>
|
233 |
+
|
234 |
+
<table border="0" cellpadding="4" cellspacing="0">
|
235 |
+
<tr>
|
236 |
+
<td class="column1"><label for="stylesheet">{#fullpage_dlg.stylesheet}</label></td>
|
237 |
+
<td><table border="0" cellpadding="0" cellspacing="0">
|
238 |
+
<tr>
|
239 |
+
<td><input id="stylesheet" name="stylesheet" type="text" value="" /></td>
|
240 |
+
<td id="stylesheet_browsercontainer"> </td>
|
241 |
+
</tr>
|
242 |
+
</table></td>
|
243 |
+
</tr>
|
244 |
+
<tr>
|
245 |
+
<td class="column1"><label for="style">{#fullpage_dlg.style}</label></td>
|
246 |
+
<td><input id="style" name="style" type="text" value="" onchange="FullPageDialog.changedStyle();" /></td>
|
247 |
+
</tr>
|
248 |
+
</table>
|
249 |
+
</fieldset>
|
250 |
+
</div>
|
251 |
+
</div>
|
252 |
+
|
253 |
+
<div class="mceActionPanel">
|
254 |
+
<input type="submit" id="insert" name="update" value="{#update}" />
|
255 |
+
<input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" />
|
256 |
+
</div>
|
257 |
+
</form>
|
258 |
+
</body>
|
259 |
+
</html>
|
tinymce-plugins/3.4.x/fullpage/js/fullpage.js
ADDED
@@ -0,0 +1,232 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* fullpage.js
|
3 |
+
*
|
4 |
+
* Copyright 2009, Moxiecode Systems AB
|
5 |
+
* Released under LGPL License.
|
6 |
+
*
|
7 |
+
* License: http://tinymce.moxiecode.com/license
|
8 |
+
* Contributing: http://tinymce.moxiecode.com/contributing
|
9 |
+
*/
|
10 |
+
|
11 |
+
(function() {
|
12 |
+
tinyMCEPopup.requireLangPack();
|
13 |
+
|
14 |
+
var defaultDocTypes =
|
15 |
+
'XHTML 1.0 Transitional=<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">,' +
|
16 |
+
'XHTML 1.0 Frameset=<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">,' +
|
17 |
+
'XHTML 1.0 Strict=<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">,' +
|
18 |
+
'XHTML 1.1=<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">,' +
|
19 |
+
'HTML 4.01 Transitional=<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">,' +
|
20 |
+
'HTML 4.01 Strict=<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">,' +
|
21 |
+
'HTML 4.01 Frameset=<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">';
|
22 |
+
|
23 |
+
var defaultEncodings =
|
24 |
+
'Western european (iso-8859-1)=iso-8859-1,' +
|
25 |
+
'Central European (iso-8859-2)=iso-8859-2,' +
|
26 |
+
'Unicode (UTF-8)=utf-8,' +
|
27 |
+
'Chinese traditional (Big5)=big5,' +
|
28 |
+
'Cyrillic (iso-8859-5)=iso-8859-5,' +
|
29 |
+
'Japanese (iso-2022-jp)=iso-2022-jp,' +
|
30 |
+
'Greek (iso-8859-7)=iso-8859-7,' +
|
31 |
+
'Korean (iso-2022-kr)=iso-2022-kr,' +
|
32 |
+
'ASCII (us-ascii)=us-ascii';
|
33 |
+
|
34 |
+
var defaultFontNames = 'Arial=arial,helvetica,sans-serif;Courier New=courier new,courier,monospace;Georgia=georgia,times new roman,times,serif;Tahoma=tahoma,arial,helvetica,sans-serif;Times New Roman=times new roman,times,serif;Verdana=verdana,arial,helvetica,sans-serif;Impact=impact;WingDings=wingdings';
|
35 |
+
var defaultFontSizes = '10px,11px,12px,13px,14px,15px,16px';
|
36 |
+
|
37 |
+
function setVal(id, value) {
|
38 |
+
var elm = document.getElementById(id);
|
39 |
+
|
40 |
+
if (elm) {
|
41 |
+
value = value || '';
|
42 |
+
|
43 |
+
if (elm.nodeName == "SELECT")
|
44 |
+
selectByValue(document.forms[0], id, value);
|
45 |
+
else if (elm.type == "checkbox")
|
46 |
+
elm.checked = !!value;
|
47 |
+
else
|
48 |
+
elm.value = value;
|
49 |
+
}
|
50 |
+
};
|
51 |
+
|
52 |
+
function getVal(id) {
|
53 |
+
var elm = document.getElementById(id);
|
54 |
+
|
55 |
+
if (elm.nodeName == "SELECT")
|
56 |
+
return elm.options[elm.selectedIndex].value;
|
57 |
+
|
58 |
+
if (elm.type == "checkbox")
|
59 |
+
return elm.checked;
|
60 |
+
|
61 |
+
return elm.value;
|
62 |
+
};
|
63 |
+
|
64 |
+
window.FullPageDialog = {
|
65 |
+
changedStyle : function() {
|
66 |
+
var val, styles = tinyMCEPopup.editor.dom.parseStyle(getVal('style'));
|
67 |
+
|
68 |
+
setVal('fontface', styles['font-face']);
|
69 |
+
setVal('fontsize', styles['font-size']);
|
70 |
+
setVal('textcolor', styles['color']);
|
71 |
+
|
72 |
+
if (val = styles['background-image'])
|
73 |
+
setVal('bgimage', val.replace(new RegExp("url\\('?([^']*)'?\\)", 'gi'), "$1"));
|
74 |
+
else
|
75 |
+
setVal('bgimage', '');
|
76 |
+
|
77 |
+
setVal('bgcolor', styles['background-color']);
|
78 |
+
|
79 |
+
// Reset margin form elements
|
80 |
+
setVal('topmargin', '');
|
81 |
+
setVal('rightmargin', '');
|
82 |
+
setVal('bottommargin', '');
|
83 |
+
setVal('leftmargin', '');
|
84 |
+
|
85 |
+
// Expand margin
|
86 |
+
if (val = styles['margin']) {
|
87 |
+
val = val.split(' ');
|
88 |
+
styles['margin-top'] = val[0] || '';
|
89 |
+
styles['margin-right'] = val[1] || val[0] || '';
|
90 |
+
styles['margin-bottom'] = val[2] || val[0] || '';
|
91 |
+
styles['margin-left'] = val[3] || val[0] || '';
|
92 |
+
}
|
93 |
+
|
94 |
+
if (val = styles['margin-top'])
|
95 |
+
setVal('topmargin', val.replace(/px/, ''));
|
96 |
+
|
97 |
+
if (val = styles['margin-right'])
|
98 |
+
setVal('rightmargin', val.replace(/px/, ''));
|
99 |
+
|
100 |
+
if (val = styles['margin-bottom'])
|
101 |
+
setVal('bottommargin', val.replace(/px/, ''));
|
102 |
+
|
103 |
+
if (val = styles['margin-left'])
|
104 |
+
setVal('leftmargin', val.replace(/px/, ''));
|
105 |
+
|
106 |
+
updateColor('bgcolor_pick', 'bgcolor');
|
107 |
+
updateColor('textcolor_pick', 'textcolor');
|
108 |
+
},
|
109 |
+
|
110 |
+
changedStyleProp : function() {
|
111 |
+
var val, dom = tinyMCEPopup.editor.dom, styles = dom.parseStyle(getVal('style'));
|
112 |
+
|
113 |
+
styles['font-face'] = getVal('fontface');
|
114 |
+
styles['font-size'] = getVal('fontsize');
|
115 |
+
styles['color'] = getVal('textcolor');
|
116 |
+
styles['background-color'] = getVal('bgcolor');
|
117 |
+
|
118 |
+
if (val = getVal('bgimage'))
|
119 |
+
styles['background-image'] = "url('" + val + "')";
|
120 |
+
else
|
121 |
+
styles['background-image'] = '';
|
122 |
+
|
123 |
+
delete styles['margin'];
|
124 |
+
|
125 |
+
if (val = getVal('topmargin'))
|
126 |
+
styles['margin-top'] = val + "px";
|
127 |
+
else
|
128 |
+
styles['margin-top'] = '';
|
129 |
+
|
130 |
+
if (val = getVal('rightmargin'))
|
131 |
+
styles['margin-right'] = val + "px";
|
132 |
+
else
|
133 |
+
styles['margin-right'] = '';
|
134 |
+
|
135 |
+
if (val = getVal('bottommargin'))
|
136 |
+
styles['margin-bottom'] = val + "px";
|
137 |
+
else
|
138 |
+
styles['margin-bottom'] = '';
|
139 |
+
|
140 |
+
if (val = getVal('leftmargin'))
|
141 |
+
styles['margin-left'] = val + "px";
|
142 |
+
else
|
143 |
+
styles['margin-left'] = '';
|
144 |
+
|
145 |
+
// Serialize, parse and reserialize this will compress redundant styles
|
146 |
+
setVal('style', dom.serializeStyle(dom.parseStyle(dom.serializeStyle(styles))));
|
147 |
+
this.changedStyle();
|
148 |
+
},
|
149 |
+
|
150 |
+
update : function() {
|
151 |
+
var data = {};
|
152 |
+
|
153 |
+
tinymce.each(tinyMCEPopup.dom.select('select,input,textarea'), function(node) {
|
154 |
+
data[node.id] = getVal(node.id);
|
155 |
+
});
|
156 |
+
|
157 |
+
tinyMCEPopup.editor.plugins.fullpage._dataToHtml(data);
|
158 |
+
tinyMCEPopup.close();
|
159 |
+
}
|
160 |
+
};
|
161 |
+
|
162 |
+
function init() {
|
163 |
+
var form = document.forms[0], i, item, list, editor = tinyMCEPopup.editor;
|
164 |
+
|
165 |
+
// Setup doctype select box
|
166 |
+
list = editor.getParam("fullpage_doctypes", defaultDocTypes).split(',');
|
167 |
+
for (i = 0; i < list.length; i++) {
|
168 |
+
item = list[i].split('=');
|
169 |
+
|
170 |
+
if (item.length > 1)
|
171 |
+
addSelectValue(form, 'doctype', item[0], item[1]);
|
172 |
+
}
|
173 |
+
|
174 |
+
// Setup fonts select box
|
175 |
+
list = editor.getParam("fullpage_fonts", defaultFontNames).split(';');
|
176 |
+
for (i = 0; i < list.length; i++) {
|
177 |
+
item = list[i].split('=');
|
178 |
+
|
179 |
+
if (item.length > 1)
|
180 |
+
addSelectValue(form, 'fontface', item[0], item[1]);
|
181 |
+
}
|
182 |
+
|
183 |
+
// Setup fontsize select box
|
184 |
+
list = editor.getParam("fullpage_fontsizes", defaultFontSizes).split(',');
|
185 |
+
for (i = 0; i < list.length; i++)
|
186 |
+
addSelectValue(form, 'fontsize', list[i], list[i]);
|
187 |
+
|
188 |
+
// Setup encodings select box
|
189 |
+
list = editor.getParam("fullpage_encodings", defaultEncodings).split(',');
|
190 |
+
for (i = 0; i < list.length; i++) {
|
191 |
+
item = list[i].split('=');
|
192 |
+
|
193 |
+
if (item.length > 1)
|
194 |
+
addSelectValue(form, 'docencoding', item[0], item[1]);
|
195 |
+
}
|
196 |
+
|
197 |
+
// Setup color pickers
|
198 |
+
document.getElementById('bgcolor_pickcontainer').innerHTML = getColorPickerHTML('bgcolor_pick','bgcolor');
|
199 |
+
document.getElementById('link_color_pickcontainer').innerHTML = getColorPickerHTML('link_color_pick','link_color');
|
200 |
+
document.getElementById('visited_color_pickcontainer').innerHTML = getColorPickerHTML('visited_color_pick','visited_color');
|
201 |
+
document.getElementById('active_color_pickcontainer').innerHTML = getColorPickerHTML('active_color_pick','active_color');
|
202 |
+
document.getElementById('textcolor_pickcontainer').innerHTML = getColorPickerHTML('textcolor_pick','textcolor');
|
203 |
+
document.getElementById('stylesheet_browsercontainer').innerHTML = getBrowserHTML('stylesheetbrowser','stylesheet','file','fullpage');
|
204 |
+
document.getElementById('bgimage_pickcontainer').innerHTML = getBrowserHTML('bgimage_browser','bgimage','image','fullpage');
|
205 |
+
|
206 |
+
// Resize some elements
|
207 |
+
if (isVisible('stylesheetbrowser'))
|
208 |
+
document.getElementById('stylesheet').style.width = '220px';
|
209 |
+
|
210 |
+
if (isVisible('link_href_browser'))
|
211 |
+
document.getElementById('element_link_href').style.width = '230px';
|
212 |
+
|
213 |
+
if (isVisible('bgimage_browser'))
|
214 |
+
document.getElementById('bgimage').style.width = '210px';
|
215 |
+
|
216 |
+
// Update form
|
217 |
+
tinymce.each(tinyMCEPopup.getWindowArg('data'), function(value, key) {
|
218 |
+
setVal(key, value);
|
219 |
+
});
|
220 |
+
|
221 |
+
FullPageDialog.changedStyle();
|
222 |
+
|
223 |
+
// Update colors
|
224 |
+
updateColor('textcolor_pick', 'textcolor');
|
225 |
+
updateColor('bgcolor_pick', 'bgcolor');
|
226 |
+
updateColor('visited_color_pick', 'visited_color');
|
227 |
+
updateColor('active_color_pick', 'active_color');
|
228 |
+
updateColor('link_color_pick', 'link_color');
|
229 |
+
};
|
230 |
+
|
231 |
+
tinyMCEPopup.onInit.add(init);
|
232 |
+
})();
|
tinymce-plugins/3.4.x/fullpage/langs/en_dlg.js
ADDED
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
tinyMCE.addI18n('en.fullpage_dlg',{
|
2 |
+
title:"Document properties",
|
3 |
+
meta_tab:"General",
|
4 |
+
appearance_tab:"Appearance",
|
5 |
+
advanced_tab:"Advanced",
|
6 |
+
meta_props:"Meta information",
|
7 |
+
langprops:"Language and encoding",
|
8 |
+
meta_title:"Title",
|
9 |
+
meta_keywords:"Keywords",
|
10 |
+
meta_description:"Description",
|
11 |
+
meta_robots:"Robots",
|
12 |
+
doctypes:"Doctype",
|
13 |
+
langcode:"Language code",
|
14 |
+
langdir:"Language direction",
|
15 |
+
ltr:"Left to right",
|
16 |
+
rtl:"Right to left",
|
17 |
+
xml_pi:"XML declaration",
|
18 |
+
encoding:"Character encoding",
|
19 |
+
appearance_bgprops:"Background properties",
|
20 |
+
appearance_marginprops:"Body margins",
|
21 |
+
appearance_linkprops:"Link colors",
|
22 |
+
appearance_textprops:"Text properties",
|
23 |
+
bgcolor:"Background color",
|
24 |
+
bgimage:"Background image",
|
25 |
+
left_margin:"Left margin",
|
26 |
+
right_margin:"Right margin",
|
27 |
+
top_margin:"Top margin",
|
28 |
+
bottom_margin:"Bottom margin",
|
29 |
+
text_color:"Text color",
|
30 |
+
font_size:"Font size",
|
31 |
+
font_face:"Font face",
|
32 |
+
link_color:"Link color",
|
33 |
+
hover_color:"Hover color",
|
34 |
+
visited_color:"Visited color",
|
35 |
+
active_color:"Active color",
|
36 |
+
textcolor:"Color",
|
37 |
+
fontsize:"Font size",
|
38 |
+
fontface:"Font family",
|
39 |
+
meta_index_follow:"Index and follow the links",
|
40 |
+
meta_index_nofollow:"Index and don't follow the links",
|
41 |
+
meta_noindex_follow:"Do not index but follow the links",
|
42 |
+
meta_noindex_nofollow:"Do not index and don\'t follow the links",
|
43 |
+
appearance_style:"Stylesheet and style properties",
|
44 |
+
stylesheet:"Stylesheet",
|
45 |
+
style:"Style",
|
46 |
+
author:"Author",
|
47 |
+
copyright:"Copyright",
|
48 |
+
add:"Add new element",
|
49 |
+
remove:"Remove selected element",
|
50 |
+
moveup:"Move selected element up",
|
51 |
+
movedown:"Move selected element down",
|
52 |
+
head_elements:"Head elements",
|
53 |
+
info:"Information",
|
54 |
+
add_title:"Title element",
|
55 |
+
add_meta:"Meta element",
|
56 |
+
add_script:"Script element",
|
57 |
+
add_style:"Style element",
|
58 |
+
add_link:"Link element",
|
59 |
+
add_base:"Base element",
|
60 |
+
add_comment:"Comment node",
|
61 |
+
title_element:"Title element",
|
62 |
+
script_element:"Script element",
|
63 |
+
style_element:"Style element",
|
64 |
+
base_element:"Base element",
|
65 |
+
link_element:"Link element",
|
66 |
+
meta_element:"Meta element",
|
67 |
+
comment_element:"Comment",
|
68 |
+
src:"Src",
|
69 |
+
language:"Language",
|
70 |
+
href:"Href",
|
71 |
+
target:"Target",
|
72 |
+
type:"Type",
|
73 |
+
charset:"Charset",
|
74 |
+
defer:"Defer",
|
75 |
+
media:"Media",
|
76 |
+
properties:"Properties",
|
77 |
+
name:"Name",
|
78 |
+
value:"Value",
|
79 |
+
content:"Content",
|
80 |
+
rel:"Rel",
|
81 |
+
rev:"Rev",
|
82 |
+
hreflang:"Href lang",
|
83 |
+
general_props:"General",
|
84 |
+
advanced_props:"Advanced"
|
85 |
+
});
|
tinymce-plugins/cmseditor/editor_plugin.js
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
(function() {
|
3 |
+
tinymce.PluginManager.requireLangPack('cmseditor');
|
4 |
+
tinymce.create('tinymce.plugins.cmseditor', {
|
5 |
+
init : function(ed, url) {
|
6 |
+
var t = this;
|
7 |
+
t.editor = ed;
|
8 |
+
|
9 |
+
// load JS
|
10 |
+
tinymce.DOM.add(tinymce.DOM.select('head'), 'script', {src: url + '/js/codemirror-compressed.js'});
|
11 |
+
//tinymce.DOM.add(tinymce.DOM.select('head'), 'script', {src: url + '/js/lib/codemirror.js'});
|
12 |
+
//tinymce.DOM.add(tinymce.DOM.select('head'), 'script', {src: url + '/js/mode/xml/xml.js'});
|
13 |
+
//tinymce.DOM.add(tinymce.DOM.select('head'), 'script', {src: url + '/js/mode/css/css.js'});
|
14 |
+
//tinymce.DOM.add(tinymce.DOM.select('head'), 'script', {src: url + '/js/mode/javascript/javascript.js'});
|
15 |
+
//tinymce.DOM.add(tinymce.DOM.select('head'), 'script', {src: url + '/js/mode/htmlmixed/htmlmixed.js'});
|
16 |
+
|
17 |
+
// load CSS
|
18 |
+
tinymce.DOM.loadCSS(url + '/js/lib/codemirror.css');
|
19 |
+
tinymce.DOM.loadCSS(url + '/js/theme/default.css');
|
20 |
+
|
21 |
+
ed.addCommand('cmseditor', function() {
|
22 |
+
t.initEditor();
|
23 |
+
}, t );
|
24 |
+
|
25 |
+
ed.addButton('cmseditor', {
|
26 |
+
title : 'CodeMirror Source Editor',
|
27 |
+
cmd : 'cmseditor',
|
28 |
+
image : url + '/img/html.gif'
|
29 |
+
});
|
30 |
+
},
|
31 |
+
initEditor : function(){
|
32 |
+
var t = this, ed = t.editor, id = ed.getElement().id, cm = document.getElementById(id);
|
33 |
+
|
34 |
+
ed.hide();
|
35 |
+
|
36 |
+
t.cmEditor = CodeMirror.fromTextArea( cm, {
|
37 |
+
matchBrackets: true,
|
38 |
+
lineNumbers : true,
|
39 |
+
mode : 'text/html'
|
40 |
+
});
|
41 |
+
t.indentAll();
|
42 |
+
t.cmEditor.refresh();
|
43 |
+
var close_btn = t.initToolBar();
|
44 |
+
close_btn.onclick = function() {
|
45 |
+
t.closeEditor(t);
|
46 |
+
};
|
47 |
+
},
|
48 |
+
initToolBar: function() {
|
49 |
+
var t = this;
|
50 |
+
t.cmWrapper = t.cmEditor.getWrapperElement();
|
51 |
+
t.cmWrapper.style.width = '100%';
|
52 |
+
|
53 |
+
t.cmWrapper.cmToolBar = document.createElement("div");
|
54 |
+
t.cmWrapper.cmToolBar.style.width = '100%';
|
55 |
+
t.cmWrapper.cmToolBar.className = 'CodeMirror-ToolBar';
|
56 |
+
t.cmWrapper.parentNode.insertBefore(t.cmWrapper.cmToolBar, t.cmWrapper);
|
57 |
+
return tinymce.DOM.add(t.cmWrapper.cmToolBar, 'input', { type: 'button', value: 'x', 'class': 'CodeMirror-ToolBar-close' });
|
58 |
+
},
|
59 |
+
closeEditor: function(t) {
|
60 |
+
var ed = t.editor;
|
61 |
+
ed.show();
|
62 |
+
ed.setContent(t.cmEditor.getValue());
|
63 |
+
t.cmWrapper.parentNode.removeChild(t.cmWrapper.cmToolBar);
|
64 |
+
t.cmWrapper.parentNode.removeChild(t.cmWrapper);
|
65 |
+
t.cmEditor = null;
|
66 |
+
},
|
67 |
+
indentAll: function() {
|
68 |
+
var lineCount = this.cmEditor.lineCount();
|
69 |
+
for(var line = 0; line < lineCount; line++) {
|
70 |
+
this.cmEditor.indentLine(line);
|
71 |
+
}
|
72 |
+
},
|
73 |
+
getInfo : function() {
|
74 |
+
return {
|
75 |
+
longname : 'CodeMirror Source Editor',
|
76 |
+
author : 'Nicolas Lemoine',
|
77 |
+
authorurl : 'http://wordpress.org/extend/plugins/wp-better-emails/',
|
78 |
+
infourl : 'http://wordpress.org/extend/plugins/wp-better-emails/',
|
79 |
+
version : '0.1'
|
80 |
+
};
|
81 |
+
}
|
82 |
+
});
|
83 |
+
tinymce.PluginManager.add('cmseditor', tinymce.plugins.cmseditor);
|
84 |
+
})();
|
tinymce-plugins/cmseditor/img/ed-bg.gif
ADDED
Binary file
|
tinymce-plugins/cmseditor/img/html.gif
ADDED
Binary file
|
tinymce-plugins/cmseditor/js/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Copyright (C) 2011 by Marijn Haverbeke <marijnh@gmail.com>
|
2 |
+
|
3 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4 |
+
of this software and associated documentation files (the "Software"), to deal
|
5 |
+
in the Software without restriction, including without limitation the rights
|
6 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7 |
+
copies of the Software, and to permit persons to whom the Software is
|
8 |
+
furnished to do so, subject to the following conditions:
|
9 |
+
|
10 |
+
The above copyright notice and this permission notice shall be included in
|
11 |
+
all copies or substantial portions of the Software.
|
12 |
+
|
13 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19 |
+
THE SOFTWARE.
|
tinymce-plugins/cmseditor/js/README.md
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# CodeMirror 2
|
2 |
+
|
3 |
+
CodeMirror 2 is a rewrite of [CodeMirror
|
4 |
+
1](http://github.com/marijnh/CodeMirror). The docs live
|
5 |
+
[here](http://codemirror.net/manual.html), and the project page is
|
6 |
+
[http://codemirror.net/](http://codemirror.net/).
|
tinymce-plugins/cmseditor/js/codemirror-compressed.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
var CodeMirror=function(){function a(b,c){function bv(a){return a>=0&&a<$.length}function bx(a){ba=null;var b={line:0,ch:0};bH(b,{line:$.length-1,ch:$[$.length-1].text.length},N(a),b,b),ba=new j,bg=!0}function by(a){var b=[];for(var c=0,d=$.length;c<d;++c)b.push($[c].text);return b.join("\n")}function bz(a){function h(){bW(),bg=!0,j(),k()}function i(a){var b=cH(a,!0);if(b&&!G(b,e)){bb||bF(),e=b,ce(d,b),bg=!1;var c=b$();if(b.line>=c.to||b.line<c.from)f=setTimeout(cU(function(){i(a)}),150)}}for(var b=p(a);b!=w;b=b.parentNode)if(b.parentNode==J&&b!=Q)return;var c=bf;bf=null;for(var b=p(a);b!=w;b=b.parentNode)if(b.parentNode==S)return g.onGutterClick&&g.onGutterClick(bw,M(S.childNodes,b)+bl,a),m(a);var d=cH(a);switch(q(a)){case 3:u&&!z&&cI(a);return;case 2:d&&cg(d.line,d.ch,!0);return}if(!d){p(a)==D&&m(a);return}bb||bF(),m(a);if(c&&+(new Date)-c<400)return cn(d.line);cg(d.line,d.ch,!0);var e=d,f,j=r(n,"mousemove",cU(function(a){clearTimeout(f),m(a),i(a)}),!0),k=r(n,"mouseup",cU(function(a){clearTimeout(f);var b=cH(a);b&&ce(d,b),m(a),h()}),!0)}function bA(a){var b=cH(a);if(!b)return;cm(b),m(a),bf=+(new Date)}function bB(a){a.preventDefault();var b=cH(a,!0),c=a.dataTransfer.files;if(!b||g.readOnly)return;if(c&&c.length&&window.FileReader&&window.File){function d(a,c){var d=new FileReader;d.onload=function(){f[c]=d.result,++h==e&&bM(f.join(""),ci(b),ci(b))},d.readAsText(a)}var e=c.length,f=Array(e),h=0;for(var i=0;i<e;++i)d(c[i],i)}else try{var f=a.dataTransfer.getData("Text");f&&bM(f,b,b)}catch(a){}}function bC(a){bb||bF();var b=a.keyCode;v&&b==27&&(a.returnValue=!1);var c=(z?a.metaKey:a.ctrlKey)&&!a.altKey,d=a.ctrlKey||a.altKey||a.metaKey;b==16||a.shiftKey?bd=bd||(bc.inverted?bc.to:bc.from):bd=null;if(g.onKeyEvent&&g.onKeyEvent(bw,l(a)))return;if(b==33||b==34)return cj(b==34),m(a);if(c&&(b==36||b==35||z&&(b==38||b==40)))return ck(b==36||b==38),m(a);if(c&&b==65)return cl(),m(a);if(!g.readOnly){if(!d&&b==13)return;if(!d&&b==9&&cp(a.shiftKey))return m(a);if(c&&b==90)return bJ(),m(a);if(c&&(a.shiftKey&&b==90||b==89))return bK(),m(a)}if(b==36&&g.smartHome)return cq(),m(a);bo=(c?"c":"")+(a.altKey?"a":"")+b;if(bc.inverted&&A[bo]===!0){var e=O(C);e&&(be={anchor:e.start},P(C,e.start,e.start))}!c&&!a.altKey&&(bo=null),bT(bo)}function bD(a){if(g.onKeyEvent&&g.onKeyEvent(bw,l(a)))return;be&&(be=null,bg=!0),a.keyCode==16&&(bd=null)}function bE(a){if(g.onKeyEvent&&g.onKeyEvent(bw,l(a)))return;if(g.electricChars&&Z.electricChars){var b=String.fromCharCode(a.charCode==null?a.keyCode:a.charCode);Z.electricChars.indexOf(b)>-1&&setTimeout(cU(function(){cr(bc.to.line,"smart")}),50)}var c=a.keyCode;c==13?(g.readOnly||co(),m(a)):!a.ctrlKey&&!a.altKey&&!a.metaKey&&c==9&&g.tabMode!="default"?m(a):bT(bo)}function bF(){if(g.readOnly=="nocursor")return;bb||(g.onFocus&&g.onFocus(bw),bb=!0,w.className.search(/\bCodeMirror-focused\b/)==-1&&(w.className+=" CodeMirror-focused"),bk||bV()),bS(),cJ()}function bG(){bb&&(g.onBlur&&g.onBlur(bw),bb=!1,w.className=w.className.replace(" CodeMirror-focused","")),clearInterval(Y),setTimeout(function(){bb||(bd=null)},150)}function bH(a,b,c,d,e){if(ba){var f=[];for(var h=a.line,i=b.line+1;h<i;++h)f.push($[h].text);ba.addChange(a.line,c.length,f);while(ba.done.length>g.undoDepth)ba.done.shift()}bL(a,b,c,d,e)}function bI(a,b){var c=a.pop();if(c){var d=[],e=c.start+c.added;for(var f=c.start;f<e;++f)d.push($[f].text);b.push({start:c.start,added:c.old.length,old:d});var g=ci({line:c.start+c.old.length-1,ch:L(d[d.length-1],c.old[c.old.length-1])});bL({line:c.start,ch:0},{line:e-1,ch:$[e-1].text.length},c.old,g,g),bg=!0}}function bJ(){bI(ba.done,ba.undone)}function bK(){bI(ba.undone,ba.done)}function bL(a,b,c,d,e){function s(a){return a<=Math.min(b.line,b.line+q)?a:a+q}var f=!1,g=br.length;for(var i=a.line;i<=b.line;++i)if($[i].text.length==g){f=!0;break}var j=b.line-a.line,k=$[a.line],l=$[b.line];if(k==l)if(c.length==1)k.replace(a.ch,b.ch,c[0]);else{l=k.split(b.ch,c[c.length-1]);var m=[a.line+1,j];k.replace(a.ch,k.text.length,c[0]);for(var i=1,n=c.length-1;i<n;++i)m.push(new h(c[i]));m.push(l),$.splice.apply($,m)}else if(c.length==1)k.replace(a.ch,k.text.length,c[0]+l.text.slice(b.ch)),$.splice(a.line+1,j);else{var m=[a.line+1,j-1];k.replace(a.ch,k.text.length,c[0]),l.replace(0,b.ch,c[c.length-1]);for(var i=1,n=c.length-1;i<n;++i)m.push(new h(c[i]));$.splice.apply($,m)}for(var i=a.line,n=i+c.length;i<n;++i){var o=$[i].text;o.length>g&&(br=o,g=o.length,bs=null,f=!1)}if(f){g=0,br="",bs=null;for(var i=0,n=$.length;i<n;++i){var o=$[i].text;o.length>g&&(g=o.length,br=o)}}var p=[],q=c.length-j-1;for(var i=0,o=_.length;i<o;++i){var r=_[i];r<a.line?p.push(r):r>b.line&&p.push(r+q)}c.length<5?(cO(a.line,a.line+c.length),p.push(a.line+c.length)):p.push(a.line),_=p,cQ(100),bh.push({from:a.line,to:b.line+1,diff:q}),bi={from:a,to:b,text:c},cf(d,e,s(bc.from.line),s(bc.to.line)),J.style.height=$.length*cE()+2*cF()+"px"}function bM(a,b,c){function d(d){if(H(d,b))return d;if(!H(c,d))return e;var f=d.line+a.length-(c.line-b.line)-1,g=d.ch;return d.line==c.line&&(g+=a[a.length-1].length-(c.ch-(c.line==b.line?b.ch:0))),{line:f,ch:g}}b=ci(b),c?c=ci(c):c=b,a=N(a);var e;return bO(a,b,c,function(a){return e=a,{from:d(bc.from),to:d(bc.to)}}),e}function bN(a,b){bO(N(a),bc.from,bc.to,function(a){return b=="end"?{from:a,to:a}:b=="start"?{from:bc.from,to:bc.from}:{from:bc.from,to:a}})}function bO(a,b,c,d){var e=a.length==1?a[0].length+b.ch:a[a.length-1].length,f=d({line:b.line+a.length-1,ch:e});bH(b,c,a,f.from,f.to)}function bP(a,b){var c=a.line,d=b.line;if(c==d)return $[c].text.slice(a.ch,b.ch);var e=[$[c].text.slice(a.ch)];for(var f=c+1;f<d;++f)e.push($[f].text);return e.push($[d].text.slice(0,b.ch)),e.join("\n")}function bQ(){return bP(bc.from,bc.to)}function bS(){if(bR)return;W.set(2e3,function(){cR(),bU(),bb&&bS(),cS()})}function bT(a){function c(){cR();var d=bU();d&&a&&(d=="moved"&&A[a]==null&&(A[a]=!0),d=="changed"&&(A[a]=!1)),!d&&!b?(b=!0,W.set(80,c)):(bR=!1,bS()),cS()}var b=!1;bR=!0,W.set(20,c)}function bU(){function f(a,c){var d=0;for(;;){var e=b.indexOf("\n",d);if(e==-1||(b.charAt(e-1)=="\r"?e-1:e)>=a)return{line:c,ch:a-d};++c,d=e+1}}if(bk||!bb)return;var a=!1,b=C.value,c=O(C);if(!c)return!1;var a=bp.text!=b,d=be,e=a||c.start!=bp.start||c.end!=(d?bp.start:bp.end);if(!e&&!d)return!1;if(a){bd=be=null;if(g.readOnly)return bg=!0,"changed"}var h=f(c.start,bp.from),i=f(c.end,bp.from);if(d){var j=c.start==d.anchor?i:h,k=bd?bc.to:c.start==d.anchor?h:i;(bc.inverted=H(j,k))?(h=j,i=k):(be=null,h=k,i=j)}h.line==i.line&&h.line==bc.from.line&&h.line==bc.to.line&&!bd&&(bg=!1);if(a){var l=0,m=b.length,n=Math.min(m,bp.text.length),o,p=bp.from,q=-1;while(l<n&&(o=b.charAt(l))==bp.text.charAt(l))++l,o=="\n"&&(p++,q=l);var r=q>-1?l-q:l,s=bp.to-1,t=bp.text.length;for(;;){o=bp.text.charAt(t);if(b.charAt(m)!=o){++m,++t;break}o=="\n"&&s--;if(t<=l||m<=l)break;--m,--t}var q=bp.text.lastIndexOf("\n",t-1),u=q==-1?t:t-q-1;bH({line:p,ch:r},{line:s,ch:u},N(b.slice(l,m)),h,i);if(p!=s||h.line!=p)bg=!0}else cf(h,i);return bp.text=b,bp.start=c.start,bp.end=c.end,a?"changed":e?"moved":!1}function bV(){var a=[],b=Math.max(0,bc.from.line-1),c=Math.min($.length,bc.to.line+2);for(var d=b;d<c;++d)a.push($[d].text);a=C.value=a.join(x);var e=bc.from.ch,f=bc.to.ch;for(var d=b;d<bc.from.line;++d)e+=x.length+$[d].text.length;for(var d=b;d<bc.to.line;++d)f+=x.length+$[d].text.length;bp={text:a,from:b,to:c,start:e,end:f},P(C,e,be?e:f)}function bW(){g.readOnly!="nocursor"&&C.focus()}function bX(){if(!U.getBoundingClientRect)return;var a=U.getBoundingClientRect(),b=window.innerHeight||document.body.offsetHeight||document.documentElement.offsetHeight;(a.top<0||a.bottom>b)&&U.scrollIntoView()}function bY(){var a=cC(bc.inverted?bc.from:bc.to);return bZ(a.x,a.y,a.x,a.yBot)}function bZ(a,b,c,d){var e=cG(),f=cF(),h=cE();b+=f,d+=f,a+=e,c+=e;var i=D.clientHeight,j=D.scrollTop,k=!1,l=!0;b<j?(D.scrollTop=Math.max(0,b-2*h),k=!0):d>j+i&&(D.scrollTop=d+h-i,k=!0);var m=D.clientWidth,n=D.scrollLeft,o=g.fixedGutter?R.clientWidth:0;return a<n+o?(a<50&&(a=0),D.scrollLeft=Math.max(0,a-10-o),k=!0):c>m+n&&(D.scrollLeft=c+10-m,k=!0,c>J.clientWidth&&(l=!1)),k&&g.onScroll&&g.onScroll(bw),l}function b$(){var a=cE(),b=D.scrollTop-cF();return{from:Math.min($.length,Math.max(0,Math.floor(b/a))),to:Math.min($.length,Math.ceil((b+D.clientHeight)/a))}}function b_(a){if(!D.clientWidth){bl=bm=0;return}var b=a===!0?[]:[{from:bl,to:bm,domStart:0}];for(var c=0,d=a.length||0;c<d;++c){var e=a[c],f=[],g=e.diff||0;for(var h=0,i=b.length;h<i;++h){var j=b[h];e.to<=j.from?f.push({from:j.from+g,to:j.to+g,domStart:j.domStart}):j.to<=e.from?f.push(j):(e.from>j.from&&f.push({from:j.from,to:e.from,domStart:j.domStart}),e.to<j.to&&f.push({from:e.to+g,to:j.to+g,domStart:j.domStart+(e.to-j.from)}))}b=f}var k=b$(),l=Math.min(bl,Math.max(k.from-3,0)),m=Math.min($.length,Math.max(bm,k.to+3)),n=[],o=0,p=bm-bl,q=l,r=0;for(var c=0,d=b.length;c<d;++c){var j=b[c];if(j.to<=l)continue;if(j.from>=m)break;if(j.domStart>o||j.from>q)n.push({from:q,to:j.from,domSize:j.domStart-o,domStart:o}),r+=j.from-q;q=j.to,o=j.domStart+(j.to-j.from)}if(o!=p||q!=m)r+=Math.abs(m-q),n.push({from:q,to:m,domSize:p-o,domStart:o});if(!n.length)return;V.style.display="none",r>(k.to-k.from)*.3?ca(l=Math.max(k.from-10,0),m=Math.min(k.to+7,$.length)):cb(n),V.style.display="";var s=l!=bl||m!=bm||bn!=D.clientHeight;bl=l,bm=m,Q.style.top=l*cE()+"px",s&&(bn=D.clientHeight,J.style.height=$.length*cE()+2*cF()+"px"),(s||n.length)&&cc(),bs==null&&(bs=cz(br)),bs>D.clientWidth?(T.style.width=bs+"px",J.style.width="",J.style.width=D.scrollWidth+"px"):T.style.width=J.style.width="";if(V.childNodes.length!=bm-bl)throw new Error("BAD PATCH! "+JSON.stringify(n)+" size="+(bm-bl)+" nodes="+V.childNodes.length);cd()}function ca(a,b){var c=[],d={line:a,ch:0},e=H(bc.from,d)&&!H(bc.to,d);for(var f=a;f<b;++f){var g=null,h=null;e?(g=0,bc.to.line==f&&(e=!1,h=bc.to.ch)):bc.from.line==f&&(bc.to.line==f?(g=bc.from.ch,h=bc.to.ch):(e=!0,g=bc.from.ch)),c.push($[f].getHTML(g,h,!0))}V.innerHTML=c.join("")}function cb(a){var b=bc.from.line,c=bc.to.line,d=0,e=t&&n.createElement("div");for(var f=0,g=a.length;f<g;++f){var h=a[f],i=h.to-h.from-h.domSize,j=V.childNodes[h.domStart+h.domSize+d]||null;if(t)for(var k=Math.max(-i,h.domSize);k>0;--k)V.removeChild(j?j.previousSibling:V.lastChild);else if(i){for(var k=Math.max(0,i);k>0;--k)V.insertBefore(n.createElement("pre"),j);for(var k=Math.max(0,-i);k>0;--k)V.removeChild(j?j.previousSibling:V.lastChild)}var l=V.childNodes[h.domStart+d],m=b<h.from&&c>=h.from;for(var k=h.from;k<h.to;++k){var o=null,p=null;m?(o=0,c==k&&(m=!1,p=bc.to.ch)):b==k&&(c==k?(o=bc.from.ch,p=bc.to.ch):(m=!0,o=bc.from.ch)),t?(e.innerHTML=$[k].getHTML(o,p,!0),V.insertBefore(e.firstChild,j)):(l.innerHTML=$[k].getHTML(o,p,!1),l.className=$[k].className||"",l=l.nextSibling)}d+=i}}function cc(){if(!g.gutter&&!g.lineNumbers)return;var a=Q.offsetHeight,b=D.clientHeight;R.style.height=(a-b<2?b:a)+"px";var c=[];for(var d=bl;d<Math.max(bm,bl+1);++d){var e=$[d].gutterMarker,f=g.lineNumbers?d+g.firstLineNumber:null;e&&e.text?f=e.text.replace("%N%",f!=null?f:""):f==null&&(f="\u00a0"),c.push(e&&e.style?'<pre class="'+e.style+'">':"<pre>",f,"</pre>")}R.style.display="none",S.innerHTML=c.join("");var h=String($.length).length,i=S.firstChild,j=F(i),k="";while(j.length+k.length<h)k+="\u00a0";k&&i.insertBefore(n.createTextNode(k),i.firstChild),R.style.display="",T.style.marginLeft=R.offsetWidth+"px"}function cd(){var a=bc.inverted?bc.from:bc.to,b=cE(),c=cA(a.line,a.ch);B.style.top=a.line*b-D.scrollTop+"px",B.style.left=c-D.scrollLeft+"px",G(bc.from,bc.to)?(U.style.top=(a.line-bl)*b+"px",U.style.left=c+"px",U.style.display=""):U.style.display="none"}function ce(a,b){var c=bd&&ci(bd);c&&(H(c,a)?a=c:H(b,c)&&(b=c)),cf(a,b)}function cf(a,b,c,d){if(G(bc.from,a)&&G(bc.to,b))return;if(H(b,a)){var e=b;b=a,a=e}G(a,b)?bc.inverted=!1:G(a,bc.to)?bc.inverted=!1:G(b,bc.from)&&(bc.inverted=!0),c==null&&(c=bc.from.line,d=bc.to.line),G(a,b)?G(bc.from,bc.to)||bh.push({from:c,to:d+1}):G(bc.from,bc.to)?bh.push({from:a.line,to:b.line+1}):(G(a,bc.from)||(a.line<c?bh.push({from:a.line,to:Math.min(b.line,c)+1}):bh.push({from:c,to:Math.min(d,a.line)+1})),G(b,bc.to)||(b.line<d?bh.push({from:Math.max(c,a.line),to:d+1}):bh.push({from:Math.max(a.line,d),to:b.line+1}))),bc.from=a,bc.to=b,bj=!0}function cg(a,b,c){var d=ci({line:a,ch:b||0});(c?ce:cf)(d,d)}function ch(a){return Math.max(0,Math.min(a,$.length-1))}function ci(a){if(a.line<0)return{line:0,ch:0};if(a.line>=$.length)return{line:$.length-1,ch:$[$.length-1].text.length};var b=a.ch,c=$[a.line].text.length;return b==null||b>c?{line:a.line,ch:c}:b<0?{line:a.line,ch:0}:a}function cj(a){var b=Math.floor(D.clientHeight/cE()),c=bc.inverted?bc.from:bc.to;cg(c.line+Math.max(b-1,1)*(a?1:-1),c.ch,!0)}function ck(a){var b=a?{line:0,ch:0}:{line:$.length-1,ch:$[$.length-1].text.length};ce(b,b)}function cl(){var a=$.length-1;cf({line:0,ch:0},{line:a,ch:$[a].text.length})}function cm(a){var b=$[a.line].text,c=a.ch,d=a.ch;while(c>0&&/\w/.test(b.charAt(c-1)))--c;while(d<b.length&&/\w/.test(b.charAt(d)))++d;ce({line:a.line,ch:c},{line:a.line,ch:d})}function cn(a){ce({line:a,ch:0},{line:a,ch:$[a].text.length})}function co(){bN("\n","end"),g.enterMode!="flat"&&cr(bc.from.line,g.enterMode=="keep"?"prev":"smart")}function cp(a){function b(a){if(G(bc.from,bc.to))return cr(bc.from.line,a);var b=bc.to.line-(bc.to.ch?0:1);for(var c=bc.from.line;c<=b;++c)cr(c,a)}bd=null;switch(g.tabMode){case"default":return!1;case"indent":b("smart");break;case"classic":if(G(bc.from,bc.to)){a?cr(bc.from.line,"smart"):bN("\t","end");break};case"shift":b(a?"subtract":"add")}return!0}function cq(){var a=Math.max(0,$[bc.from.line].text.search(/\S/));cg(bc.from.line,bc.from.ch<=a&&bc.from.ch?0:a,!0)}function cr(a,b){if(b=="smart")if(!Z.indent)b="prev";else var c=cN(a);var d=$[a],e=d.indentation(),f=d.text.match(/^\s*/)[0],h;b=="prev"?a?h=$[a-1].indentation():h=0:b=="smart"?h=Z.indent(c,d.text.slice(f.length)):b=="add"?h=e+g.indentUnit:b=="subtract"&&(h=e-g.indentUnit),h=Math.max(0,h);var i=h-e;if(!i){if(bc.from.line!=a&&bc.to.line!=a)return;var j=f}else{var j="",k=0;if(g.indentWithTabs)for(var l=Math.floor(h/y);l;--l)k+=y,j+="\t";while(k<h)++k,j+=" "}bM(j,{line:a,ch:0},{line:a,ch:f.length})}function cs(){Z=a.getMode(g,g.mode);for(var b=0,c=$.length;b<c;++b)$[b].stateAfter=null;_=[0],cQ()}function ct(){var a=g.gutter||g.lineNumbers;R.style.display=a?"":"none",a?cc():V.parentNode.style.marginLeft=0}function cu(a,b,c){function e(a,b,c,e){var a=$[a],f=a.addMark(b,c,e);f.line=a,d.push(f)}a=ci(a),b=ci(b);var d=[];if(a.line==b.line)e(a.line,a.ch,b.ch,c);else{e(a.line,a.ch,null,c);for(var f=a.line+1,g=b.line;f<g;++f)e(f,0,null,c);e(b.line,0,b.ch,c)}return bh.push({from:a.line,to:b.line+1}),function(){var a,b;for(var c=0;c<d.length;++c){var e=d[c],f=M($,e.line);e.line.removeMark(e),f>-1&&(a==null&&(a=f),b=f)}a!=null&&bh.push({from:a,to:b+1})}}function cv(a,b,c){return typeof a=="number"&&(a=$[ch(a)]),a.gutterMarker={text:b,style:c},cc(),a}function cw(a){typeof a=="number"&&(a=$[ch(a)]),a.gutterMarker=null,cc()}function cx(a,b){if(typeof a=="number"){var c=a;a=$[ch(a)]}else{var c=M($,a);if(c==-1)return null}return a.className!=b&&(a.className=b,bh.push({from:c,to:c+1})),a}function cy(a){if(typeof a=="number"){var b=a;a=$[a];if(!a)return null}else{var b=M($,a);if(b==-1)return null}var c=a.gutterMarker;return{line:b,text:a.text,markerText:c&&c.text,markerClass:c&&c.style}}function cz(a){return K.innerHTML="<pre><span>x</span></pre>",K.firstChild.firstChild.firstChild.nodeValue=a,K.firstChild.firstChild.offsetWidth||10}function cA(a,b){return b==0?0:(K.innerHTML="<pre><span>"+$[a].getHTML(null,null,!1,b)+"</span></pre>",K.firstChild.firstChild.offsetWidth)}function cB(a,b){function e(a){return K.innerHTML="<pre><span>"+c.getHTML(null,null,!1,a)+"</span></pre>",K.firstChild.firstChild.offsetWidth}if(b<=0)return 0;var c=$[a],d=c.text,f=0,g=0,h=d.length,i,j=Math.min(h,Math.ceil(b/cz("x")));for(;;){var k=e(j);if(k<=b&&j<h)j=Math.min(h,Math.ceil(j*1.2));else{i=k,h=j;break}}if(b>i)return h;j=Math.floor(h*.8),k=e(j),k<b&&(f=j,g=k);for(;;){if(h-f<=1)return i-b>b-g?f:h;var l=Math.ceil((f+h)/2),m=e(l);m>b?(h=l,i=m):(f=l,g=m)}}function cC(a,b){var c=cE(),d=a.line-(b?bl:0);return{x:cA(a.line,a.ch),y:d*c,yBot:(d+1)*c}}function cD(a){var b=cC(a,!0),c=E(T);return{x:c.left+b.x,y:c.top+b.y,yBot:c.top+b.yBot}}function cE(){var a=V.childNodes.length;return a?V.offsetHeight/a||1:(K.innerHTML="<pre>x</pre>",K.firstChild.offsetHeight||1)}function cF(){return T.offsetTop}function cG(){return T.offsetLeft}function cH(a,b){var c=E(D,!0),d,e;try{d=a.clientX,e=a.clientY}catch(a){return null}if(!b&&(d-c.left>D.clientWidth||e-c.top>D.clientHeight))return null;var f=E(T,!0),g=bl+Math.floor((e-f.top)/cE());return ci({line:g,ch:cB(ch(g),d-f.left)})}function cI(a){function e(){var a=N(C.value).join("\n");a!=d&&cU(bN)(a,"end"),B.style.position="relative",C.style.cssText=c,bk=!1,bV(),bS()}var b=cH(a);if(!b||window.opera)return;(G(bc.from,bc.to)||H(b,bc.from)||!H(b,bc.to))&&cU(cg)(b.line,b.ch);var c=C.style.cssText;B.style.position="absolute",C.style.cssText="position: fixed; width: 30px; height: 30px; top: "+(a.clientY-5)+"px; left: "+(a.clientX-5)+"px; z-index: 1000; background: white; "+"border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);",bk=!0;var d=C.value=bQ();bW(),P(C,0,C.value.length);if(u){o(a);var f=r(window,"mouseup",function(){f(),setTimeout(e,20)},!0)}else setTimeout(e,50)}function cJ(){clearInterval(Y);var a=!0;U.style.visibility="",Y=setInterval(function(){U.style.visibility=(a=!a)?"":"hidden"},650)}function cL(a){function p(a,b,c){if(!a.text)return;var d=a.styles,e=g?0:a.text.length-1,f;for(var i=g?0:d.length-2,j=g?d.length:-2;i!=j;i+=2*h){var k=d[i];if(d[i+1]!=null&&d[i+1]!=m){e+=h*k.length;continue}for(var l=g?0:k.length-1,p=g?k.length:-1;l!=p;l+=h,e+=h)if(e>=b&&e<c&&o.test(f=k.charAt(l))){var q=cK[f];if(q.charAt(1)==">"==g)n.push(f);else{if(n.pop()!=q.charAt(0))return{pos:e,match:!1};if(!n.length)return{pos:e,match:!0}}}}}var b=bc.inverted?bc.from:bc.to,c=$[b.line],d=b.ch-1,e=d>=0&&cK[c.text.charAt(d)]||cK[c.text.charAt(++d)];if(!e)return;var f=e.charAt(0),g=e.charAt(1)==">",h=g?1:-1,i=c.styles;for(var j=d+1,k=0,l=i.length;k<l;k+=2)if((j-=i[k].length)<=0){var m=i[k+1];break}var n=[c.text.charAt(d)],o=/[(){}[\]]/;for(var k=b.line,l=g?Math.min(k+100,$.length):Math.max(-1,k-100);k!=l;k+=h){var c=$[k],q=k==b.line,r=p(c,q&&g?d+1:0,q&&!g?d:c.text.length);if(r)break}r||(r={pos:null,match:!1});var m=r.match?"CodeMirror-matchingbracket":"CodeMirror-nonmatchingbracket",s=cu({line:b.line,ch:d},{line:b.line,ch:d+1},m),t=r.pos!=null?cu({line:k,ch:r.pos},{line:k,ch:r.pos+1},m):function(){},u=cU(function(){s(),t()});a?setTimeout(u,800):bq=u}function cM(a){var b,c;for(var d=a,e=a-40;d>e;--d){if(d==0)return 0;var f=$[d-1];if(f.stateAfter)return d;var g=f.indentation();if(c==null||b>g)c=d-1,b=g}return c}function cN(a){var b=cM(a),c=b&&$[b-1].stateAfter;c?c=e(Z,c):c=f(Z);for(var d=b;d<a;++d){var g=$[d];g.highlight(Z,c),g.stateAfter=e(Z,c)}return a<$.length&&!$[a].stateAfter&&_.push(a),c}function cO(a,b){var c=cN(a);for(var d=a;d<b;++d){var f=$[d];f.highlight(Z,c),f.stateAfter=e(Z,c)}}function cP(){var a=+(new Date)+g.workTime,b=_.length;while(_.length){if(!$[bl].stateAfter)var c=bl;else var c=_.pop();if(c>=$.length)continue;var d=cM(c),h=d&&$[d-1].stateAfter;h?h=e(Z,h):h=f(Z);var i=0,j=Z.compareStates,k=!1;for(var l=d,m=$.length;l<m;++l){var n=$[l],o=n.stateAfter;if(+(new Date)>a){_.push(l),cQ(g.workDelay),k&&bh.push({from:c,to:l+1});return}var p=n.highlight(Z,h);p&&(k=!0),n.stateAfter=e(Z,h);if(j){if(o&&j(o,h))break}else if(p!==!1||!o)i=0;else if(++i>3)break}k&&bh.push({from:c,to:l+1})}b&&g.onHighlightComplete&&g.onHighlightComplete(bw)}function cQ(a){if(!_.length)return;X.set(a,cU(cP))}function cR(){bg=null,bh=[],bi=bj=!1}function cS(){var a=!1;bj&&(a=!bY()),bh.length?b_(bh):bj&&cd(),a&&bY(),bj&&(bX(),cJ()),bb&&!bk&&(bg===!0||bg!==!1&&bj)&&bV(),bj&&g.matchBrackets&&setTimeout(cU(function(){bq&&(bq(),bq=null),cL(!1)}),20);var b=bi;bj&&g.onCursorActivity&&g.onCursorActivity(bw),b&&g.onChange&&bw&&g.onChange(bw,b)}function cU(a){return function(){cT++||cR();try{var b=a.apply(this,arguments)}finally{--cT||cS()}return b}}function cV(a,b,c){this.atOccurrence=!1,c==null&&(c=typeof a=="string"&&a==a.toLowerCase()),b&&typeof b=="object"?b=ci(b):b={line:0,ch:0},this.pos={from:b,to:b};if(typeof a!="string")this.matches=function(b,c){if(b){var d=$[c.line].text.slice(0,c.ch),e=d.match(a),f=0;while(e){var g=d.indexOf(e[0]);f+=g,d=d.slice(g+1);var h=d.match(a);if(h)e=h;else break;f++}}else var d=$[c.line].text.slice(c.ch),e=d.match(a),f=e&&c.ch+d.indexOf(e[0]);if(e)return{from:{line:c.line,ch:f},to:{line:c.line,ch:f+e[0].length},match:e}};else{c&&(a=a.toLowerCase());var d=c?function(a){return a.toLowerCase()}:function(a){return a},e=a.split("\n");e.length==1?this.matches=function(b,c){var e=d($[c.line].text),f=a.length,g;if(b?c.ch>=f&&(g=e.lastIndexOf(a,c.ch-f))!=-1:(g=e.indexOf(a,c.ch))!=-1)return{from:{line:c.line,ch:g},to:{line:c.line,ch:g+f}}}:this.matches=function(a,b){var c=b.line,f=a?e.length-1:0,g=e[f],h=d($[c].text),i=a?h.indexOf(g)+g.length:h.lastIndexOf(g);if(a?i>=b.ch||i!=g.length:i<=b.ch||i!=h.length-g.length)return;for(;;){if(a?!c:c==$.length-1)return;h=d($[c+=a?-1:1].text),g=e[a?--f:++f];if(f>0&&f<e.length-1){if(h!=g)return;continue}var j=a?h.lastIndexOf(g):h.indexOf(g)+g.length;if(a?j!=h.length-g.length:j!=g.length)return;var k={line:b.line,ch:i},l={line:c,ch:j};return{from:a?l:k,to:a?k:l}}}}}var g={},i=a.defaults;for(var k in i)i.hasOwnProperty(k)&&(g[k]=(c&&c.hasOwnProperty(k)?c:i)[k]);var n=g.document,w=n.createElement("div");w.className="CodeMirror",w.innerHTML='<div style="overflow: hidden; position: relative; width: 1px; height: 0px;"><textarea style="position: absolute; width: 2px;" wrap="off"></textarea></div><div class="CodeMirror-scroll cm-s-'+g.theme+'">'+'<div style="position: relative">'+'<div style="position: absolute; height: 0; width: 0; overflow: hidden;"></div>'+'<div style="position: relative">'+'<div class="CodeMirror-gutter"><div class="CodeMirror-gutter-text"></div></div>'+'<div class="CodeMirror-lines"><div style="position: relative">'+'<pre class="CodeMirror-cursor"> </pre>'+"<div></div>"+"</div></div></div></div></div>",b.appendChild?b.appendChild(w):b(w);var B=w.firstChild,C=B.firstChild,D=w.lastChild,J=D.firstChild,K=J.firstChild,Q=K.nextSibling,R=Q.firstChild,S=R.firstChild,T=R.nextSibling.firstChild,U=T.firstChild,V=U.nextSibling;g.tabindex!=null&&(C.tabindex=g.tabindex),!g.gutter&&!g.lineNumbers&&(R.style.display="none");var W=new s,X=new s,Y,Z,$=[new h("")],_,ba=new j,bb;cs();var bc={from:{line:0,ch:0},to:{line:0,ch:0},inverted:!1},bd,be,bf,bg,bh,bi,bj,bk,bl=0,bm=0,bn=0,bo=null,bp,bq,br="",bs;cU(function(){bx(g.value||""),bg=!1})(),r(D,"mousedown",cU(bz)),u||r(D,"contextmenu",cI),r(J,"dblclick",cU(bA)),r(D,"scroll",function(){b_([]),g.fixedGutter&&(R.style.left=D.scrollLeft+"px"),g.onScroll&&g.onScroll(bw)}),r(window,"resize",function(){b_(!0)}),r(C,"keyup",cU(bD)),r(C,"keydown",cU(bC)),r(C,"keypress",cU(bE)),r(C,"focus",bF),r(C,"blur",bG),r(D,"dragenter",o),r(D,"dragover",o),r(D,"drop",cU(bB)),r(D,"paste",function(){bW(),bT()}),r(C,"paste",function(){bT()}),r(C,"cut",function(){bT()});var bt;try{bt=n.activeElement==C}catch(bu){}bt?setTimeout(bF,20):bG();var bw={getValue:by,setValue:cU(bx),getSelection:bQ,replaceSelection:cU(bN),focus:function(){bW(),bF(),bT()},setOption:function(a,b){g[a]=b,a=="lineNumbers"||a=="gutter"||a=="firstLineNumber"?ct():a=="mode"||a=="indentUnit"?cs():a=="readOnly"&&b=="nocursor"?C.blur():a=="theme"&&(D.className=D.className.replace(/cm-s-\w+/,"cm-s-"+b))},getOption:function(a){return g[a]},undo:cU(bJ),redo:cU(bK),indentLine:cU(function(a,b){bv(a)&&cr(a,b==null?"smart":b?"add":"subtract")}),historySize:function(){return{undo:ba.done.length,redo:ba.undone.length}},matchBrackets:cU(function(){cL(!0)}),getTokenAt:function(a){return a=ci(a),$[a.line].getTokenAt(Z,cN(a.line),a.ch)},getStateAfter:function(a){return a=ch(a==null?$.length-1:a),cN(a+1)},cursorCoords:function(a){return a==null&&(a=bc.inverted),cD(a?bc.from:bc.to)},charCoords:function(a){return cD(ci(a))},coordsChar:function(a){var b=E(T),c=ch(Math.min($.length-1,bl+Math.floor((a.y-b.top)/cE())));return ci({line:c,ch:cB(ch(c),a.x-b.left)})},getSearchCursor:function(a,b,c){return new cV(a,b,c)},markText:cU(function(a,b,c){return cU(cu(a,b,c))}),setMarker:cv,clearMarker:cw,setLineClass:cU(cx),lineInfo:cy,addWidget:function(a,b,c,d){a=cC(ci(a));var e=a.yBot,f=a.x;b.style.position="absolute",J.appendChild(b),b.style.left=f+"px";if(d=="over")e=a.y;else if(d=="near"){var g=Math.max(D.offsetHeight,$.length*cE()),h=Math.max(J.clientWidth,T.clientWidth)-cG();a.yBot+b.offsetHeight>g&&a.y>b.offsetHeight&&(e=a.y-b.offsetHeight),f+b.offsetWidth>h&&(f=h-b.offsetWidth)}b.style.top=e+cF()+"px",b.style.left=f+cG()+"px",c&&bZ(f,e,f+b.offsetWidth,e+b.offsetHeight)},lineCount:function(){return $.length},getCursor:function(a){return a==null&&(a=bc.inverted),I(a?bc.from:bc.to)},somethingSelected:function(){return!G(bc.from,bc.to)},setCursor:cU(function(a,b){b==null&&typeof a.line=="number"?cg(a.line,a.ch):cg(a,b)}),setSelection:cU(function(a,b){cf(ci(a),ci(b||a))}),getLine:function(a){if(bv(a))return $[a].text},setLine:cU(function(a,b){bv(a)&&bM(b,{line:a,ch:0},{line:a,ch:$[a].text.length})}),removeLine:cU(function(a){bv(a)&&bM("",{line:a,ch:0},ci({line:a+1,ch:0}))}),replaceRange:cU(bM),getRange:function(a,b){return bP(ci(a),ci(b))},operation:function(a){return cU(a)()},refresh:function(){b_(!0)},getInputField:function(){return C},getWrapperElement:function(){return w},getScrollerElement:function(){return D},getGutterElement:function(){return R}},bR=!1,cK={"(":")>",")":"(<","[":"]>","]":"[<","{":"}>","}":"{<"},cT=0;cV.prototype={findNext:function(){return this.find(!1)},findPrevious:function(){return this.find(!0)},find:function(a){function d(a){var c={line:a,ch:0};return b.pos={from:c,to:c},b.atOccurrence=!1,!1}var b=this,c=ci(a?this.pos.from:this.pos.to);for(;;){if(this.pos=this.matches(a,c))return this.atOccurrence=!0,this.pos.match||!0;if(a){if(!c.line)return d(0);c={line:c.line-1,ch:$[c.line-1].text.length}}else{if(c.line==$.length-1)return d($.length);c={line:c.line+1,ch:0}}}},from:function(){if(this.atOccurrence)return I(this.pos.from)},to:function(){if(this.atOccurrence)return I(this.pos.to)},replace:function(a){var b=this;this.atOccurrence&&cU(function(){b.pos.to=bM(a,b.pos.from,b.pos.to)})()}};for(var cW in d)d.propertyIsEnumerable(cW)&&!bw.propertyIsEnumerable(cW)&&(bw[cW]=d[cW]);return bw}function e(a,b){if(b===!0)return b;if(a.copyState)return a.copyState(b);var c={};for(var d in b){var e=b[d];e instanceof Array&&(e=e.concat([])),c[d]=e}return c}function f(a,b,c){return a.startState?a.startState(b,c):!0}function g(a){this.pos=this.start=0,this.string=a}function h(a,b){this.styles=b||[a,null],this.stateAfter=null,this.text=a,this.marked=this.gutterMarker=this.className=null}function i(a,b,c,d){for(var e=0,f=0,g=0;f<b;e+=2){var h=c[e],i=f+h.length;g==0?(i>a&&d.push(h.slice(a-f,Math.min(h.length,b-f)),c[e+1]),i>=a&&(g=1)):g==1&&(i>b?d.push(h.slice(0,b-f),c[e+1]):d.push(h,c[e+1])),f=i}}function j(){this.time=0,this.done=[],this.undone=[]}function k(){o(this)}function l(a){return a.stop||(a.stop=k),a}function m(a){a.preventDefault?a.preventDefault():a.returnValue=!1}function n(a){a.stopPropagation?a.stopPropagation():a.cancelBubble=!0}function o(a){m(a),n(a)}function p(a){return a.target||a.srcElement}function q(a){if(a.which)return a.which;if(a.button&1)return 1;if(a.button&2)return 3;if(a.button&4)return 2}function r(a,b,c,d){function e(a){c(a||window.event)}if(typeof a.addEventListener=="function"){a.addEventListener(b,e,!1);if(d)return function(){a.removeEventListener(b,e,!1)}}else{a.attachEvent("on"+b,e);if(d)return function(){a.detachEvent("on"+b,e)}}}function s(){this.id=null}function C(a,b){b==null&&(b=a.search(/[^\s\u00a0]/),b==-1&&(b=a.length));for(var c=0,d=0;c<b;++c)a.charAt(c)=="\t"?d+=y-d%y:++d;return d}function D(a){return a.currentStyle?a.currentStyle:window.getComputedStyle(a,null)}function E(a,b){var c=a.ownerDocument.body,d=0,e=0,f=!1;for(var g=a;g;g=g.offsetParent)d+=g.offsetLeft,e+=g.offsetTop,b&&D(g).position=="fixed"&&(f=!0);var h=b&&!f?null:c;for(var g=a.parentNode;g!=h;g=g.parentNode)g.scrollLeft!=null&&(d-=g.scrollLeft,e-=g.scrollTop);return{left:d,top:e}}function F(a){return a.textContent||a.innerText||a.nodeValue||""}function G(a,b){return a.line==b.line&&a.ch==b.ch}function H(a,b){return a.line<b.line||a.line==b.line&&a.ch<b.ch}function I(a){return{line:a.line,ch:a.ch}}function K(a){return J.innerText=J.textContent=a,J.innerHTML}function L(a,b){if(!b)return a?a.length:0;if(!a)return b.length;for(var c=a.length,d=b.length;c>=0&&d>=0;--c,--d)if(a.charAt(c)!=b.charAt(d))break;return d+1}function M(a,b){if(a.indexOf)return a.indexOf(b);for(var c=0,d=a.length;c<d;++c)if(a[c]==b)return c;return-1}a.defaults={value:"",mode:null,theme:"default",indentUnit:2,indentWithTabs:!1,tabMode:"classic",enterMode:"indent",electricChars:!0,onKeyEvent:null,lineNumbers:!1,gutter:!1,fixedGutter:!1,firstLineNumber:1,readOnly:!1,smartHome:!0,onChange:null,onCursorActivity:null,onGutterClick:null,onHighlightComplete:null,onFocus:null,onBlur:null,onScroll:null,matchBrackets:!1,workTime:100,workDelay:200,undoDepth:40,tabindex:null,document:window.document};var b={},c={};a.defineMode=function(c,d){!a.defaults.mode&&c!="null"&&(a.defaults.mode=c),b[c]=d},a.defineMIME=function(a,b){c[a]=b},a.getMode=function(d,e){typeof e=="string"&&c.hasOwnProperty(e)&&(e=c[e]);if(typeof e=="string")var f=e,g={};else if(e!=null)var f=e.name,g=e;var h=b[f];return h?h(d,g||{}):(window.console&&console.warn("No mode "+f+" found, falling back to plain text."),a.getMode(d,"text/plain"))},a.listModes=function(){var a=[];for(var c in b)b.propertyIsEnumerable(c)&&a.push(c);return a},a.listMIMEs=function(){var a=[];for(var b in c)c.propertyIsEnumerable(b)&&a.push(b);return a};var d={};a.defineExtension=function(a,b){d[a]=b},a.fromTextArea=function(b,c){function d(){b.value=h.getValue()}c||(c={}),c.value=b.value,!c.tabindex&&b.tabindex&&(c.tabindex=b.tabindex);if(b.form){var e=r(b.form,"submit",d,!0);if(typeof b.form.submit=="function"){var f=b.form.submit;function g(){d(),b.form.submit=f,b.form.submit(),b.form.submit=g}b.form.submit=g}}b.style.display="none";var h=a(function(a){b.parentNode.insertBefore(a,b.nextSibling)},c);return h.save=d,h.toTextArea=function(){d(),b.parentNode.removeChild(h.getWrapperElement()),b.style.display="",b.form&&(e(),typeof b.form.submit=="function"&&(b.form.submit=f))},h},a.startState=f,a.copyState=e,g.prototype={eol:function(){return this.pos>=this.string.length},sol:function(){return this.pos==0},peek:function(){return this.string.charAt(this.pos)},next:function(){if(this.pos<this.string.length)return this.string.charAt(this.pos++)},eat:function(a){var b=this.string.charAt(this.pos);if(typeof a=="string")var c=b==a;else var c=b&&(a.test?a.test(b):a(b));if(c)return++this.pos,b},eatWhile:function(a){var b=this.pos;while(this.eat(a));return this.pos>b},eatSpace:function(){var a=this.pos;while(/[\s\u00a0]/.test(this.string.charAt(this.pos)))++this.pos;return this.pos>a},skipToEnd:function(){this.pos=this.string.length},skipTo:function(a){var b=this.string.indexOf(a,this.pos);if(b>-1)return this.pos=b,!0},backUp:function(a){this.pos-=a},column:function(){return C(this.string,this.start)},indentation:function(){return C(this.string)},match:function(a,b,c){if(typeof a!="string"){var e=this.string.slice(this.pos).match(a);return e&&b!==!1&&(this.pos+=e[0].length),e}function d(a){return c?a.toLowerCase():a}if(d(this.string).indexOf(d(a),this.pos)==this.pos)return b!==!1&&(this.pos+=a.length),!0},current:function(){return this.string.slice(this.start,this.pos)}},a.StringStream=g,h.prototype={replace:function(a,b,c){var d=[],e=this.marked;i(0,a,this.styles,d),c&&d.push(c,null),i(b,this.text.length,this.styles,d),this.styles=d,this.text=this.text.slice(0,a)+c+this.text.slice(b),this.stateAfter=null;if(e){var f=c.length-(b-a),g=this.text.length;function h(a){return a<=Math.min(b,b+f)?a:a+f}for(var j=0;j<e.length;++j){var k=e[j],l=!1;k.from>=g?l=!0:(k.from=h(k.from),k.to!=null&&(k.to=h(k.to)));if(l||k.from>=k.to)e.splice(j,1),j--}}},split:function(a,b){var c=[b,null];return i(a,this.text.length,this.styles,c),new h(b+this.text.slice(a),c)},addMark:function(a,b,c){var d=this.marked,e={from:a,to:b,style:c};return this.marked==null&&(this.marked=[]),this.marked.push(e),this.marked.sort(function(a,b){return a.from-b.from}),e},removeMark:function(a){var b=this.marked;if(!b)return;for(var c=0;c<b.length;++c)if(b[c]==a){b.splice(c,1);break}},highlight:function(a,b){var c=new g(this.text),d=this.styles,e=0,f=!1,h=d[0],i;this.text==""&&a.blankLine&&a.blankLine(b);while(!c.eol()){var j=a.token(c,b),k=this.text.slice(c.start,c.pos);c.start=c.pos,e&&d[e-1]==j?d[e-2]+=k:k&&(!f&&(d[e+1]!=j||e&&d[e-2]!=i)&&(f=!0),d[e++]=k,d[e++]=j,i=h,h=d[e]);if(c.pos>5e3){d[e++]=this.text.slice(c.pos),d[e++]=null;break}}return d.length!=e&&(d.length=e,f=!0),e&&d[e-2]!=i&&(f=!0),f||(d.length<5&&this.text.length<10?null:!1)},getTokenAt:function(a,b,c){var d=this.text,e=new g(d);while(e.pos<c&&!e.eol()){e.start=e.pos;var f=a.token(e,b)}return{start:e.start,end:e.pos,string:e.current(),className:f||null,state:b}},indentation:function(){return C(this.text)},getHTML:function(a,b,c,d){function f(a,b){if(!a)return;b?e.push('<span class="',b,'">',K(a),"</span>"):e.push(K(a))}var e=[];c&&e.push(this.className?'<pre class="'+this.className+'">':"<pre>");var g=this.styles,h=this.text,i=this.marked;a==b&&(a=null);var j=h.length;d!=null&&(j=Math.min(d,j));if(!h&&d==null)f(" ",a!=null&&b==null?"CodeMirror-selected":null);else if(!i&&a==null)for(var k=0,l=0;l<j;k+=2){var m=g[k],n=m.length;l+n>j&&(m=m.slice(0,j-l)),l+=n,f(m,"cm-"+g[k+1])}else{var o=0,k=0,p="",q,r=0,s=-1,t=null;function u(){i&&(s+=1,t=s<i.length?i[s]:null)}u();while(o<j){var v=j,w="";if(a!=null)if(a>o)v=a;else if(b==null||b>o)w=" CodeMirror-selected",b!=null&&(v=Math.min(v,b));while(t&&t.to!=null&&t.to<=o)u();t&&(t.from>o?v=Math.min(v,t.from):(w+=" "+t.style,t.to!=null&&(v=Math.min(v,t.to))));for(;;){var x=o+p.length,y=q;w&&(y=q?q+w:w),f(x>v?p.slice(0,v-o):p,y);if(x>=v){p=p.slice(v-o),o=v;break}o=x,p=g[k++],q="cm-"+g[k++]}}a!=null&&b==null&&f(" ","CodeMirror-selected")}return c&&e.push("</pre>"),e.join("")}},j.prototype={addChange:function(a,b,c){this.undone.length=0;var d=+(new Date),e=this.done[this.done.length-1];if(d-this.time>400||!e||e.start>a+b||e.start+e.added<a-e.added+e.old.length)this.done.push({start:a,added:b,old:c});else{var f=0;if(a<e.start){for(var g=e.start-a-1;g>=0;--g)e.old.unshift(c[g]);e.added+=e.start-a,e.start=a}else e.start<a&&(f=a-e.start,b+=f);for(var g=e.added-f,h=c.length;g<h;++g)e.old.push(c[g]);e.added<b&&(e.added=b)}this.time=d}},s.prototype={set:function(a,b){clearTimeout(this.id),this.id=setTimeout(b,a)}};var t=function(){var a=document.createElement("pre");return a.innerHTML=" ",!a.innerHTML}(),u=/gecko\/\d{7}/i.test(navigator.userAgent),v=/MSIE \d/.test(navigator.userAgent),w=/Apple Computer/.test(navigator.vendor),x="\n";(function(){var a=document.createElement("textarea");a.value="foo\nbar",a.value.indexOf("\r")>-1&&(x="\r\n")})();var y=8,z=/Mac/.test(navigator.platform),A={};for(var B=35;B<=40;++B)A[B]=A["c"+B]=!0;var J=document.createElement("div");a.htmlEscape=K;var N,O,P;return"\n\nb".split(/\n/).length!=3?N=function(a){var b=0,c,d=[];while((c=a.indexOf("\n",b))>-1)d.push(a.slice(b,a.charAt(c-1)=="\r"?c-1:c)),b=c+1;return d.push(a.slice(b)),d}:N=function(a){return a.split(/\r?\n/)},a.splitLines=N,window.getSelection?(O=function(a){try{return{start:a.selectionStart,end:a.selectionEnd}}catch(b){return null}},w?P=function(a,b,c){b==c?a.setSelectionRange(b,c):(a.setSelectionRange(b,c-1),window.getSelection().modify("extend","forward","character"))}:P=function(a,b,c){try{a.setSelectionRange(b,c)}catch(d){}}):(O=function(a){try{var b=a.ownerDocument.selection.createRange()}catch(c){return null}if(!b||b.parentElement()!=a)return null;var d=a.value,e=d.length,f=a.createTextRange();f.moveToBookmark(b.getBookmark());var g=a.createTextRange();g.collapse(!1);if(f.compareEndPoints("StartToEnd",g)>-1)return{start:e,end:e};var h=-f.moveStart("character",-e);for(var i=d.indexOf("\r");i>-1&&i<h;i=d.indexOf("\r",i+1),h++);if(f.compareEndPoints("EndToEnd",g)>-1)return{start:h,end:e};var j=-f.moveEnd("character",-e);for(var i=d.indexOf("\r");i>-1&&i<j;i=d.indexOf("\r",i+1),j++);return{start:h,end:j}},P=function(a,b,c){var d=a.createTextRange();d.collapse(!0);var e=d.duplicate(),f=0,g=a.value;for(var h=g.indexOf("\n");h>-1&&h<b;h=g.indexOf("\n",h+1))++f;d.move("character",b-f);for(;h>-1&&h<c;h=g.indexOf("\n",h+1))++f;e.move("character",c-f),d.setEndPoint("EndToEnd",e),d.select()}),a.defineMode("null",function(){return{token:function(a){a.skipToEnd()}}}),a.defineMIME("text/plain","null"),a}();CodeMirror.defineMode("javascript",function(a,b){function g(a,b,c){return b.tokenize=c,c(a,b)}function h(a,b){var c=!1,d;while((d=a.next())!=null){if(d==b&&!c)return!1;c=!c&&d=="\\"}return c}function k(a,b,c){return i=a,j=c,b}function l(a,b){var c=a.next();if(c=='"'||c=="'")return g(a,b,m(c));if(/[\[\]{}\(\),;\:\.]/.test(c))return k(c);if(c=="0"&&a.eat(/x/i))return a.eatWhile(/[\da-f]/i),k("number","number");if(/\d/.test(c))return a.match(/^\d*(?:\.\d*)?(?:e[+\-]?\d+)?/),k("number","number");if(c=="/")return a.eat("*")?g(a,b,n):a.eat("/")?(a.skipToEnd(),k("comment","comment")):b.reAllowed?(h(a,"/"),a.eatWhile(/[gimy]/),k("regexp","string")):(a.eatWhile(f),k("operator",null,a.current()));if(f.test(c))return a.eatWhile(f),k("operator",null,a.current());a.eatWhile(/[\w\$_]/);var d=a.current(),i=e.propertyIsEnumerable(d)&&e[d];return i?k(i.type,i.style,d):k("variable","variable",d)}function m(a){return function(b,c){return h(b,a)||(c.tokenize=l),k("string","string")}}function n(a,b){var c=!1,d;while(d=a.next()){if(d=="/"&&c){b.tokenize=l;break}c=d=="*"}return k("comment","comment")}function p(a,b,c,d,e,f){this.indented=a,this.column=b,this.type=c,this.prev=e,this.info=f,d!=null&&(this.align=d)}function q(a,b){for(var c=a.localVars;c;c=c.next)if(c.name==b)return!0}function r(a,b,c,e,f){var g=a.cc;s.state=a,s.stream=f,s.marked=null,s.cc=g,a.lexical.hasOwnProperty("align")||(a.lexical.align=!0);for(;;){var h=g.length?g.pop():d?D:C;if(h(c,e)){while(g.length&&g[g.length-1].lex)g.pop()();return s.marked?s.marked:c=="variable"&&q(a,e)?"variable-2":b}}}function t(){for(var a=arguments.length-1;a>=0;a--)s.cc.push(arguments[a])}function u(){return t.apply(null,arguments),!0}function v(a){var b=s.state;if(b.context){s.marked="def";for(var c=b.localVars;c;c=c.next)if(c.name==a)return;b.localVars={name:a,next:b.localVars}}}function x(){s.state.context||(s.state.localVars=w),s.state.context={prev:s.state.context,vars:s.state.localVars}}function y(){s.state.localVars=s.state.context.vars,s.state.context=s.state.context.prev}function z(a,b){var c=function(){var c=s.state;c.lexical=new p(c.indented,s.stream.column(),a,null,c.lexical,b)};return c.lex=!0,c}function A(){var a=s.state;a.lexical.prev&&(a.lexical.type==")"&&(a.indented=a.lexical.indented),a.lexical=a.lexical.prev)}function B(a){return function b(b){return b==a?u():a==";"?t():u(arguments.callee)}}function C(a){return a=="var"?u(z("vardef"),K,B(";"),A):a=="keyword a"?u(z("form"),D,C,A):a=="keyword b"?u(z("form"),C,A):a=="{"?u(z("}"),J,A):a==";"?u():a=="function"?u(Q):a=="for"?u(z("form"),B("("),z(")"),M,B(")"),A,C,A):a=="variable"?u(z("stat"),F):a=="switch"?u(z("form"),D,z("}","switch"),B("{"),J,A,A):a=="case"?u(D,B(":")):a=="default"?u(B(":")):a=="catch"?u(z("form"),x,B("("),R,B(")"),C,A,y):t(z("stat"),D,B(";"),A)}function D(a){return o.hasOwnProperty(a)?u(E):a=="function"?u(Q):a=="keyword c"?u(D):a=="("?u(z(")"),D,B(")"),A,E):a=="operator"?u(D):a=="["?u(z("]"),I(D,"]"),A,E):a=="{"?u(z("}"),I(H,"}"),A,E):u()}function E(a,b){if(a=="operator"&&/\+\+|--/.test(b))return u(E);if(a=="operator")return u(D);if(a==";")return;if(a=="(")return u(z(")"),I(D,")"),A,E);if(a==".")return u(G,E);if(a=="[")return u(z("]"),D,B("]"),A,E)}function F(a){return a==":"?u(A,C):t(E,B(";"),A)}function G(a){if(a=="variable")return s.marked="property",u()}function H(a){a=="variable"&&(s.marked="property");if(o.hasOwnProperty(a))return u(B(":"),D)}function I(a,b){function c(d){return d==","?u(a,c):d==b?u():u(B(b))}return function d(d){return d==b?u():t(a,c)}}function J(a){return a=="}"?u():t(C,J)}function K(a,b){return a=="variable"?(v(b),u(L)):u()}function L(a,b){if(b=="=")return u(D,L);if(a==",")return u(K)}function M(a){return a=="var"?u(K,O):a==";"?t(O):a=="variable"?u(N):t(O)}function N(a,b){return b=="in"?u(D):u(E,O)}function O(a,b){return a==";"?u(P):b=="in"?u(D):u(D,B(";"),P)}function P(a){a!=")"&&u(D)}function Q(a,b){if(a=="variable")return v(b),u(Q);if(a=="(")return u(z(")"),x,I(R,")"),A,C,y)}function R(a,b){if(a=="variable")return v(b),u()}var c=a.indentUnit,d=b.json,e=function(){function a(a){return{type:a,style:"keyword"}}var b=a("keyword a"),c=a("keyword b"),d=a("keyword c"),e=a("operator"),f={type:"atom",style:"atom"};return{"if":b,"while":b,"with":b,"else":c,"do":c,"try":c,"finally":c,"return":d,"break":d,"continue":d,"new":d,"delete":d,"throw":d,"var":a("var"),"function":a("function"),"catch":a("catch"),"for":a("for"),"switch":a("switch"),"case":a("case"),"default":a("default"),"in":e,"typeof":e,"instanceof":e,"true":f,"false":f,"null":f,"undefined":f,NaN:f,Infinity:f}}(),f=/[+\-*&%=<>!?|]/,i,j,o={atom:!0,number:!0,variable:!0,string:!0,regexp:!0},s={state:null,column:null,marked:null,cc:null},w={name:"this",next:{name:"arguments"}};return A.lex=!0,{startState:function(a){return{tokenize:l,reAllowed:!0,cc:[],lexical:new p((a||0)-c,0,"block",!1),localVars:null,context:null,indented:0}},token:function(a,b){a.sol()&&(b.lexical.hasOwnProperty("align")||(b.lexical.align=!1),b.indented=a.indentation());if(a.eatSpace())return null;var c=b.tokenize(a,b);return i=="comment"?c:(b.reAllowed=i=="operator"||i=="keyword c"||i.match(/^[\[{}\(,;:]$/),r(b,c,i,j,a))},indent:function(a,b){if(a.tokenize!=l)return 0;var d=b&&b.charAt(0),e=a.lexical,f=e.type,g=d==f;return f=="vardef"?e.indented+4:f=="form"&&d=="{"?e.indented:f=="stat"||f=="form"?e.indented+c:e.info=="switch"&&!g?e.indented+(/^(?:case|default)\b/.test(b)?c:2*c):e.align?e.column+(g?0:1):e.indented+(g?0:c)},electricChars:":{}"}}),CodeMirror.defineMIME("text/javascript","javascript"),CodeMirror.defineMIME("application/json",{name:"javascript",json:!0}),CodeMirror.defineMode("xml",function(a,b){function h(a,b){function c(c){return b.tokenize=c,c(a,b)}var d=a.next();if(d=="<"){if(a.eat("!"))return a.eat("[")?a.match("CDATA[")?c(k("atom","]]>")):null:a.match("--")?c(k("comment","-->")):a.match("DOCTYPE",!0,!0)?(a.eatWhile(/[\w\._\-]/),c(k("meta",">"))):null;if(a.eat("?"))return a.eatWhile(/[\w\._\-]/),b.tokenize=k("meta","?>"),"meta";g=a.eat("/")?"closeTag":"openTag",a.eatSpace(),f="";var e;while(e=a.eat(/[^\s\u00a0=<>\"\'\/?]/))f+=e;return b.tokenize=i,"tag"}return d=="&"?(a.eatWhile(/[^;]/),a.eat(";"),"atom"):(a.eatWhile(/[^&<]/),null)}function i(a,b){var c=a.next();return c==">"||c=="/"&&a.eat(">")?(b.tokenize=h,g=c==">"?"endTag":"selfcloseTag","tag"):c=="="?(g="equals",null):/[\'\"]/.test(c)?(b.tokenize=j(c),b.tokenize(a,b)):(a.eatWhile(/[^\s\u00a0=<>\"\'\/?]/),"word")}function j(a){return function(b,c){while(!b.eol())if(b.next()==a){c.tokenize=i;break}return"string"}}function k(a,b){return function(c,d){while(!c.eol()){if(c.match(b)){d.tokenize=h;break}c.next()}return a}}function n(){for(var a=arguments.length-1;a>=0;a--)l.cc.push(arguments[a])}function o(){return n.apply(null,arguments),!0}function p(a,b){var c=d.doNotIndent.hasOwnProperty(a)||l.context&&l.context.noIndent;l.context={prev:l.context,tagName:a,indent:l.indented,startOfLine:b,noIndent:c}}function q(){l.context&&(l.context=l.context.prev)}function r(a){if(a=="openTag")return l.tagName=f,o(u,s(l.startOfLine));if(a=="closeTag"){var b=!1;return l.context?b=l.context.tagName!=f:b=!0,b&&(m="error"),o(t(b))}return a=="string"?((!l.context||l.context.name!="!cdata")&&p("!cdata"),l.tokenize==h&&q(),o()):o()}function s(a){return function(b){return b=="selfcloseTag"||b=="endTag"&&d.autoSelfClosers.hasOwnProperty(l.tagName.toLowerCase())?o():b=="endTag"?(p(l.tagName,a),o()):o()}}function t(a){return function(b){return a&&(m="error"),b=="endTag"?(q(),o()):n()}}function u(a){return a=="word"?(m="attribute",o(u)):a=="equals"?o(v,u):n()}function v(a){return a=="word"&&d.allowUnquoted?(m="string",o()):a=="string"?o(w):n()}function w(a){return a=="string"?o(w):n()}var c=a.indentUnit,d=b.htmlMode?{autoSelfClosers:{br:!0,img:!0,hr:!0,link:!0,input:!0,meta:!0,col:!0,frame:!0,base:!0,area:!0},doNotIndent:{pre:!0,"!cdata":!0},allowUnquoted:!0}:{autoSelfClosers:{},doNotIndent:{"!cdata":!0},allowUnquoted:!1},e=b.alignCDATA,f,g,l,m;return{startState:function(){return{tokenize:h,cc:[],indented:0,startOfLine:!0,tagName:null,context:null}},token:function(a,b){a.sol()&&(b.startOfLine=!0,b.indented=a.indentation());if(a.eatSpace())return null;m=g=f=null;var c=b.tokenize(a,b);if((c||g)&&c!="comment"){l=b;for(;;){var d=b.cc.pop()||r;if(d(g||c))break}}return b.startOfLine=!1,m||c},indent:function(a,b){var d=a.context;if(d&&d.noIndent)return 0;if(e&&/<!\[CDATA\[/.test(b))return 0;d&&/^<\//.test(b)&&(d=d.prev);while(d&&!d.startOfLine)d=d.prev;return d?d.indent+c:0},compareStates:function(a,b){if(a.indented!=b.indented)return!1;for(var c=a.context,d=b.context;;c=c.prev,d=d.prev){if(!c||!d)return c==d;if(c.tagName!=d.tagName)return!1}},electricChars:"/"}}),CodeMirror.defineMIME("application/xml","xml"),CodeMirror.defineMIME("text/html",{name:"xml",htmlMode:!0}),CodeMirror.defineMode("css",function(a){function d(a,b){return c=b,a}function e(a,b){var c=a.next();if(c=="@")return a.eatWhile(/\w/),d("meta",a.current());if(c=="/"&&a.eat("*"))return b.tokenize=f,f(a,b);if(c=="<"&&a.eat("!"))return b.tokenize=g,g(a,b);if(c=="=")d(null,"compare");else return c!="~"&&c!="|"||!a.eat("=")?c=='"'||c=="'"?(b.tokenize=h(c),b.tokenize(a,b)):c=="#"?(a.eatWhile(/\w/),d("atom","hash")):c=="!"?(a.match(/^\s*\w*/),d("keyword","important")):/\d/.test(c)?(a.eatWhile(/[\w.%]/),d("number","unit")):/[,.+>*\/]/.test(c)?d(null,"select-op"):/[;{}:\[\]]/.test(c)?d(null,c):(a.eatWhile(/[\w\\\-_]/),d("variable","variable")):d(null,"compare")}function f(a,b){var c=!1,f;while((f=a.next())!=null){if(c&&f=="/"){b.tokenize=e;break}c=f=="*"}return d("comment","comment")}function g(a,b){var c=0,f;while((f=a.next())!=null){if(c>=2&&f==">"){b.tokenize=e;break}c=f=="-"?c+1:0}return d("comment","comment")}function h(a){return function(b,c){var f=!1,g;while((g=b.next())!=null){if(g==a&&!f)break;f=!f&&g=="\\"}return f||(c.tokenize=e),d("string","string")}}var b=a.indentUnit,c;return{startState:function(a){return{tokenize:e,baseIndent:a||0,stack:[]}},token:function(a,b){if(a.eatSpace())return null;var d=b.tokenize(a,b),e=b.stack[b.stack.length-1];if(c=="hash"&&e=="rule")d="atom";else if(d=="variable")if(e=="rule")d="number";else if(!e||e=="@media{")d="tag";return e=="rule"&&/^[\{\};]$/.test(c)&&b.stack.pop(),c=="{"?e=="@media"?b.stack[b.stack.length-1]="@media{":b.stack.push("{"):c=="}"?b.stack.pop():c=="@media"?b.stack.push("@media"):e=="{"&&c!="comment"&&b.stack.push("rule"),d},indent:function(a,c){var d=a.stack.length;return/^\}/.test(c)&&(d-=a.stack[a.stack.length-1]=="rule"?2:1),a.baseIndent+d*b},electricChars:"}"}}),CodeMirror.defineMIME("text/css","css"),CodeMirror.defineMode("htmlmixed",function(a,b){function f(a,b){var f=c.token(a,b.htmlState);return f=="tag"&&a.current()==">"&&b.htmlState.context&&(/^script$/i.test(b.htmlState.context.tagName)?(b.token=h,b.localState=d.startState(c.indent(b.htmlState,"")),b.mode="javascript"):/^style$/i.test(b.htmlState.context.tagName)&&(b.token=i,b.localState=e.startState(c.indent(b.htmlState,"")),b.mode="css")),f}function g(a,b,c){var d=a.current(),e=d.search(b);return e>-1&&a.backUp(d.length-e),c}function h(a,b){return a.match(/^<\/\s*script\s*>/i,!1)?(b.token=f,b.curState=null,b.mode="html",f(a,b)):g(a,/<\/\s*script\s*>/,d.token(a,b.localState))}function i(a,b){return a.match(/^<\/\s*style\s*>/i,!1)?(b.token=f,b.localState=null,b.mode="html",f(a,b)):g(a,/<\/\s*style\s*>/,e.token(a,b.localState))}var c=CodeMirror.getMode(a,{name:"xml",htmlMode:!0}),d=CodeMirror.getMode(a,"javascript"),e=CodeMirror.getMode(a,"css");return{startState:function(){var a=c.startState();return{token:f,localState:null,mode:"html",htmlState:a}},copyState:function(a){if(a.localState)var b=CodeMirror.copyState(a.token==i?e:d,a.localState);return{token:a.token,localState:b,mode:a.mode,htmlState:CodeMirror.copyState(c,a.htmlState)}},token:function(a,b){return b.token(a,b)},indent:function(a,b){return a.token==f||/^\s*<\//.test(b)?c.indent(a.htmlState,b):a.token==h?d.indent(a.localState,b):e.indent(a.localState,b)},electricChars:"/{}:"}}),CodeMirror.defineMIME("text/html","htmlmixed")
|
tinymce-plugins/cmseditor/js/lib/codemirror.css
ADDED
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.CodeMirror {
|
2 |
+
line-height: 1em;
|
3 |
+
font-family: monospace;
|
4 |
+
}
|
5 |
+
|
6 |
+
.CodeMirror-scroll {
|
7 |
+
overflow: auto;
|
8 |
+
height: 380px;
|
9 |
+
/* This is needed to prevent an IE[67] bug where the scrolled content
|
10 |
+
is visible outside of the scrolling box. */
|
11 |
+
position: relative;
|
12 |
+
}
|
13 |
+
|
14 |
+
.CodeMirror-gutter {
|
15 |
+
position: absolute; left: 0; top: 0;
|
16 |
+
background-color: #f7f7f7;
|
17 |
+
border-right: 1px solid #eee;
|
18 |
+
min-width: 2em;
|
19 |
+
height: 100%;
|
20 |
+
}
|
21 |
+
.CodeMirror-gutter-text {
|
22 |
+
color: #aaa;
|
23 |
+
text-align: right;
|
24 |
+
padding: .4em .2em .4em .4em;
|
25 |
+
}
|
26 |
+
.CodeMirror-lines {
|
27 |
+
padding: .4em;
|
28 |
+
}
|
29 |
+
|
30 |
+
.CodeMirror pre {
|
31 |
+
-moz-border-radius: 0;
|
32 |
+
-webkit-border-radius: 0;
|
33 |
+
-o-border-radius: 0;
|
34 |
+
border-radius: 0;
|
35 |
+
border-width: 0; margin: 0; padding: 0; background: transparent;
|
36 |
+
font-family: inherit;
|
37 |
+
font-size: inherit;
|
38 |
+
padding: 0; margin: 0;
|
39 |
+
white-space: pre;
|
40 |
+
word-wrap: normal;
|
41 |
+
}
|
42 |
+
|
43 |
+
.CodeMirror textarea {
|
44 |
+
font-family: inherit !important;
|
45 |
+
font-size: inherit !important;
|
46 |
+
}
|
47 |
+
|
48 |
+
.CodeMirror-cursor {
|
49 |
+
z-index: 10;
|
50 |
+
position: absolute;
|
51 |
+
visibility: hidden;
|
52 |
+
border-left: 1px solid black !important;
|
53 |
+
}
|
54 |
+
.CodeMirror-focused .CodeMirror-cursor {
|
55 |
+
visibility: visible;
|
56 |
+
}
|
57 |
+
|
58 |
+
span.CodeMirror-selected {
|
59 |
+
background: #ccc !important;
|
60 |
+
color: HighlightText !important;
|
61 |
+
}
|
62 |
+
.CodeMirror-focused span.CodeMirror-selected {
|
63 |
+
background: Highlight !important;
|
64 |
+
}
|
65 |
+
|
66 |
+
.CodeMirror-matchingbracket {color: #0f0 !important;}
|
67 |
+
.CodeMirror-nonmatchingbracket {color: #f22 !important;}
|
68 |
+
|
69 |
+
|
70 |
+
/* Tool bar */
|
71 |
+
|
72 |
+
.CodeMirror-ToolBar {
|
73 |
+
background: #eee url(../../img/ed-bg.gif) repeat-x;
|
74 |
+
border: solid 1px #ccc;
|
75 |
+
height: 30px;
|
76 |
+
text-align: right;
|
77 |
+
}
|
78 |
+
.CodeMirror-ToolBar-close {
|
79 |
+
margin: 3px;
|
80 |
+
padding: 2px 3px;
|
81 |
+
cursor: pointer;
|
82 |
+
}
|
tinymce-plugins/cmseditor/js/lib/codemirror.js
ADDED
@@ -0,0 +1,2157 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// All functions that need access to the editor's state live inside
|
2 |
+
// the CodeMirror function. Below that, at the bottom of the file,
|
3 |
+
// some utilities are defined.
|
4 |
+
|
5 |
+
// CodeMirror is the only global var we claim
|
6 |
+
var CodeMirror = (function() {
|
7 |
+
// This is the function that produces an editor instance. It's
|
8 |
+
// closure is used to store the editor state.
|
9 |
+
function CodeMirror(place, givenOptions) {
|
10 |
+
// Determine effective options based on given values and defaults.
|
11 |
+
var options = {}, defaults = CodeMirror.defaults;
|
12 |
+
for (var opt in defaults)
|
13 |
+
if (defaults.hasOwnProperty(opt))
|
14 |
+
options[opt] = (givenOptions && givenOptions.hasOwnProperty(opt) ? givenOptions : defaults)[opt];
|
15 |
+
|
16 |
+
var targetDocument = options["document"];
|
17 |
+
// The element in which the editor lives.
|
18 |
+
var wrapper = targetDocument.createElement("div");
|
19 |
+
wrapper.className = "CodeMirror";
|
20 |
+
// This mess creates the base DOM structure for the editor.
|
21 |
+
wrapper.innerHTML =
|
22 |
+
'<div style="overflow: hidden; position: relative; width: 1px; height: 0px;">' + // Wraps and hides input textarea
|
23 |
+
'<textarea style="position: absolute; width: 2px;" wrap="off"></textarea></div>' +
|
24 |
+
'<div class="CodeMirror-scroll cm-s-' + options.theme + '">' +
|
25 |
+
'<div style="position: relative">' + // Set to the height of the text, causes scrolling
|
26 |
+
'<div style="position: absolute; height: 0; width: 0; overflow: hidden;"></div>' +
|
27 |
+
'<div style="position: relative">' + // Moved around its parent to cover visible view
|
28 |
+
'<div class="CodeMirror-gutter"><div class="CodeMirror-gutter-text"></div></div>' +
|
29 |
+
// Provides positioning relative to (visible) text origin
|
30 |
+
'<div class="CodeMirror-lines"><div style="position: relative">' +
|
31 |
+
'<pre class="CodeMirror-cursor"> </pre>' + // Absolutely positioned blinky cursor
|
32 |
+
'<div></div>' + // This DIV contains the actual code
|
33 |
+
'</div></div></div></div></div>';
|
34 |
+
if (place.appendChild) place.appendChild(wrapper); else place(wrapper);
|
35 |
+
// I've never seen more elegant code in my life.
|
36 |
+
var inputDiv = wrapper.firstChild, input = inputDiv.firstChild,
|
37 |
+
scroller = wrapper.lastChild, code = scroller.firstChild,
|
38 |
+
measure = code.firstChild, mover = measure.nextSibling,
|
39 |
+
gutter = mover.firstChild, gutterText = gutter.firstChild,
|
40 |
+
lineSpace = gutter.nextSibling.firstChild,
|
41 |
+
cursor = lineSpace.firstChild, lineDiv = cursor.nextSibling;
|
42 |
+
if (options.tabindex != null) input.tabindex = options.tabindex;
|
43 |
+
if (!options.gutter && !options.lineNumbers) gutter.style.display = "none";
|
44 |
+
|
45 |
+
// Delayed object wrap timeouts, making sure only one is active. blinker holds an interval.
|
46 |
+
var poll = new Delayed(), highlight = new Delayed(), blinker;
|
47 |
+
|
48 |
+
// mode holds a mode API object. lines an array of Line objects
|
49 |
+
// (see Line constructor), work an array of lines that should be
|
50 |
+
// parsed, and history the undo history (instance of History
|
51 |
+
// constructor).
|
52 |
+
var mode, lines = [new Line("")], work, history = new History(), focused;
|
53 |
+
loadMode();
|
54 |
+
// The selection. These are always maintained to point at valid
|
55 |
+
// positions. Inverted is used to remember that the user is
|
56 |
+
// selecting bottom-to-top.
|
57 |
+
var sel = {from: {line: 0, ch: 0}, to: {line: 0, ch: 0}, inverted: false};
|
58 |
+
// Selection-related flags. shiftSelecting obviously tracks
|
59 |
+
// whether the user is holding shift. reducedSelection is a hack
|
60 |
+
// to get around the fact that we can't create inverted
|
61 |
+
// selections. See below.
|
62 |
+
var shiftSelecting, reducedSelection, lastDoubleClick;
|
63 |
+
// Variables used by startOperation/endOperation to track what
|
64 |
+
// happened during the operation.
|
65 |
+
var updateInput, changes, textChanged, selectionChanged, leaveInputAlone;
|
66 |
+
// Current visible range (may be bigger than the view window).
|
67 |
+
var showingFrom = 0, showingTo = 0, lastHeight = 0, curKeyId = null;
|
68 |
+
// editing will hold an object describing the things we put in the
|
69 |
+
// textarea, to help figure out whether something changed.
|
70 |
+
// bracketHighlighted is used to remember that a backet has been
|
71 |
+
// marked.
|
72 |
+
var editing, bracketHighlighted;
|
73 |
+
// Tracks the maximum line length so that the horizontal scrollbar
|
74 |
+
// can be kept static when scrolling.
|
75 |
+
var maxLine = "", maxWidth;
|
76 |
+
|
77 |
+
// Initialize the content.
|
78 |
+
operation(function(){setValue(options.value || ""); updateInput = false;})();
|
79 |
+
|
80 |
+
// Register our event handlers.
|
81 |
+
connect(scroller, "mousedown", operation(onMouseDown));
|
82 |
+
// Gecko browsers fire contextmenu *after* opening the menu, at
|
83 |
+
// which point we can't mess with it anymore. Context menu is
|
84 |
+
// handled in onMouseDown for Gecko.
|
85 |
+
if (!gecko) connect(scroller, "contextmenu", onContextMenu);
|
86 |
+
connect(code, "dblclick", operation(onDblClick));
|
87 |
+
connect(scroller, "scroll", function() {updateDisplay([]); if (options.onScroll) options.onScroll(instance);});
|
88 |
+
connect(window, "resize", function() {updateDisplay(true);});
|
89 |
+
connect(input, "keyup", operation(onKeyUp));
|
90 |
+
connect(input, "keydown", operation(onKeyDown));
|
91 |
+
connect(input, "keypress", operation(onKeyPress));
|
92 |
+
connect(input, "focus", onFocus);
|
93 |
+
connect(input, "blur", onBlur);
|
94 |
+
|
95 |
+
connect(scroller, "dragenter", e_stop);
|
96 |
+
connect(scroller, "dragover", e_stop);
|
97 |
+
connect(scroller, "drop", operation(onDrop));
|
98 |
+
connect(scroller, "paste", function(){focusInput(); fastPoll();});
|
99 |
+
connect(input, "paste", function(){fastPoll();});
|
100 |
+
connect(input, "cut", function(){fastPoll();});
|
101 |
+
|
102 |
+
// IE throws unspecified error in certain cases, when
|
103 |
+
// trying to access activeElement before onload
|
104 |
+
var hasFocus; try { hasFocus = (targetDocument.activeElement == input); } catch(e) { }
|
105 |
+
if (hasFocus) setTimeout(onFocus, 20);
|
106 |
+
else onBlur();
|
107 |
+
|
108 |
+
function isLine(l) {return l >= 0 && l < lines.length;}
|
109 |
+
// The instance object that we'll return. Mostly calls out to
|
110 |
+
// local functions in the CodeMirror function. Some do some extra
|
111 |
+
// range checking and/or clipping. operation is used to wrap the
|
112 |
+
// call so that changes it makes are tracked, and the display is
|
113 |
+
// updated afterwards.
|
114 |
+
var instance = {
|
115 |
+
getValue: getValue,
|
116 |
+
setValue: operation(setValue),
|
117 |
+
getSelection: getSelection,
|
118 |
+
replaceSelection: operation(replaceSelection),
|
119 |
+
focus: function(){focusInput(); onFocus(); fastPoll();},
|
120 |
+
setOption: function(option, value) {
|
121 |
+
options[option] = value;
|
122 |
+
if (option == "lineNumbers" || option == "gutter" || option == "firstLineNumber") gutterChanged();
|
123 |
+
else if (option == "mode" || option == "indentUnit") loadMode();
|
124 |
+
else if (option == "readOnly" && value == "nocursor") input.blur();
|
125 |
+
else if (option == "theme") scroller.className = scroller.className.replace(/cm-s-\w+/, "cm-s-" + value);
|
126 |
+
},
|
127 |
+
getOption: function(option) {return options[option];},
|
128 |
+
undo: operation(undo),
|
129 |
+
redo: operation(redo),
|
130 |
+
indentLine: operation(function(n, dir) {
|
131 |
+
if (isLine(n)) indentLine(n, dir == null ? "smart" : dir ? "add" : "subtract");
|
132 |
+
}),
|
133 |
+
historySize: function() {return {undo: history.done.length, redo: history.undone.length};},
|
134 |
+
matchBrackets: operation(function(){matchBrackets(true);}),
|
135 |
+
getTokenAt: function(pos) {
|
136 |
+
pos = clipPos(pos);
|
137 |
+
return lines[pos.line].getTokenAt(mode, getStateBefore(pos.line), pos.ch);
|
138 |
+
},
|
139 |
+
getStateAfter: function(line) {
|
140 |
+
line = clipLine(line == null ? lines.length - 1: line);
|
141 |
+
return getStateBefore(line + 1);
|
142 |
+
},
|
143 |
+
cursorCoords: function(start){
|
144 |
+
if (start == null) start = sel.inverted;
|
145 |
+
return pageCoords(start ? sel.from : sel.to);
|
146 |
+
},
|
147 |
+
charCoords: function(pos){return pageCoords(clipPos(pos));},
|
148 |
+
coordsChar: function(coords) {
|
149 |
+
var off = eltOffset(lineSpace);
|
150 |
+
var line = clipLine(Math.min(lines.length - 1, showingFrom + Math.floor((coords.y - off.top) / lineHeight())));
|
151 |
+
return clipPos({line: line, ch: charFromX(clipLine(line), coords.x - off.left)});
|
152 |
+
},
|
153 |
+
getSearchCursor: function(query, pos, caseFold) {return new SearchCursor(query, pos, caseFold);},
|
154 |
+
markText: operation(function(a, b, c){return operation(markText(a, b, c));}),
|
155 |
+
setMarker: addGutterMarker,
|
156 |
+
clearMarker: removeGutterMarker,
|
157 |
+
setLineClass: operation(setLineClass),
|
158 |
+
lineInfo: lineInfo,
|
159 |
+
addWidget: function(pos, node, scroll, where) {
|
160 |
+
pos = localCoords(clipPos(pos));
|
161 |
+
var top = pos.yBot, left = pos.x;
|
162 |
+
node.style.position = "absolute";
|
163 |
+
code.appendChild(node);
|
164 |
+
node.style.left = left + "px";
|
165 |
+
if (where == "over") top = pos.y;
|
166 |
+
else if (where == "near") {
|
167 |
+
var vspace = Math.max(scroller.offsetHeight, lines.length * lineHeight()),
|
168 |
+
hspace = Math.max(code.clientWidth, lineSpace.clientWidth) - paddingLeft();
|
169 |
+
if (pos.yBot + node.offsetHeight > vspace && pos.y > node.offsetHeight)
|
170 |
+
top = pos.y - node.offsetHeight;
|
171 |
+
if (left + node.offsetWidth > hspace)
|
172 |
+
left = hspace - node.offsetWidth;
|
173 |
+
}
|
174 |
+
node.style.top = (top + paddingTop()) + "px";
|
175 |
+
node.style.left = (left + paddingLeft()) + "px";
|
176 |
+
if (scroll)
|
177 |
+
scrollIntoView(left, top, left + node.offsetWidth, top + node.offsetHeight);
|
178 |
+
},
|
179 |
+
|
180 |
+
lineCount: function() {return lines.length;},
|
181 |
+
getCursor: function(start) {
|
182 |
+
if (start == null) start = sel.inverted;
|
183 |
+
return copyPos(start ? sel.from : sel.to);
|
184 |
+
},
|
185 |
+
somethingSelected: function() {return !posEq(sel.from, sel.to);},
|
186 |
+
setCursor: operation(function(line, ch) {
|
187 |
+
if (ch == null && typeof line.line == "number") setCursor(line.line, line.ch);
|
188 |
+
else setCursor(line, ch);
|
189 |
+
}),
|
190 |
+
setSelection: operation(function(from, to) {setSelection(clipPos(from), clipPos(to || from));}),
|
191 |
+
getLine: function(line) {if (isLine(line)) return lines[line].text;},
|
192 |
+
setLine: operation(function(line, text) {
|
193 |
+
if (isLine(line)) replaceRange(text, {line: line, ch: 0}, {line: line, ch: lines[line].text.length});
|
194 |
+
}),
|
195 |
+
removeLine: operation(function(line) {
|
196 |
+
if (isLine(line)) replaceRange("", {line: line, ch: 0}, clipPos({line: line+1, ch: 0}));
|
197 |
+
}),
|
198 |
+
replaceRange: operation(replaceRange),
|
199 |
+
getRange: function(from, to) {return getRange(clipPos(from), clipPos(to));},
|
200 |
+
|
201 |
+
operation: function(f){return operation(f)();},
|
202 |
+
refresh: function(){updateDisplay(true);},
|
203 |
+
getInputField: function(){return input;},
|
204 |
+
getWrapperElement: function(){return wrapper;},
|
205 |
+
getScrollerElement: function(){return scroller;},
|
206 |
+
getGutterElement: function(){return gutter;}
|
207 |
+
};
|
208 |
+
|
209 |
+
function setValue(code) {
|
210 |
+
history = null;
|
211 |
+
var top = {line: 0, ch: 0};
|
212 |
+
updateLines(top, {line: lines.length - 1, ch: lines[lines.length-1].text.length},
|
213 |
+
splitLines(code), top, top);
|
214 |
+
history = new History();
|
215 |
+
}
|
216 |
+
function getValue(code) {
|
217 |
+
var text = [];
|
218 |
+
for (var i = 0, l = lines.length; i < l; ++i)
|
219 |
+
text.push(lines[i].text);
|
220 |
+
return text.join("\n");
|
221 |
+
}
|
222 |
+
|
223 |
+
function onMouseDown(e) {
|
224 |
+
// Check whether this is a click in a widget
|
225 |
+
for (var n = e_target(e); n != wrapper; n = n.parentNode)
|
226 |
+
if (n.parentNode == code && n != mover) return;
|
227 |
+
var ld = lastDoubleClick; lastDoubleClick = null;
|
228 |
+
// First, see if this is a click in the gutter
|
229 |
+
for (var n = e_target(e); n != wrapper; n = n.parentNode)
|
230 |
+
if (n.parentNode == gutterText) {
|
231 |
+
if (options.onGutterClick)
|
232 |
+
options.onGutterClick(instance, indexOf(gutterText.childNodes, n) + showingFrom);
|
233 |
+
return e_preventDefault(e);
|
234 |
+
}
|
235 |
+
|
236 |
+
var start = posFromMouse(e);
|
237 |
+
|
238 |
+
switch (e_button(e)) {
|
239 |
+
case 3:
|
240 |
+
if (gecko && !mac) onContextMenu(e);
|
241 |
+
return;
|
242 |
+
case 2:
|
243 |
+
if (start) setCursor(start.line, start.ch, true);
|
244 |
+
return;
|
245 |
+
}
|
246 |
+
// For button 1, if it was clicked inside the editor
|
247 |
+
// (posFromMouse returning non-null), we have to adjust the
|
248 |
+
// selection.
|
249 |
+
if (!start) {if (e_target(e) == scroller) e_preventDefault(e); return;}
|
250 |
+
|
251 |
+
if (!focused) onFocus();
|
252 |
+
e_preventDefault(e);
|
253 |
+
if (ld && +new Date - ld < 400) return selectLine(start.line);
|
254 |
+
|
255 |
+
setCursor(start.line, start.ch, true);
|
256 |
+
var last = start, going;
|
257 |
+
// And then we have to see if it's a drag event, in which case
|
258 |
+
// the dragged-over text must be selected.
|
259 |
+
function end() {
|
260 |
+
focusInput();
|
261 |
+
updateInput = true;
|
262 |
+
move(); up();
|
263 |
+
}
|
264 |
+
function extend(e) {
|
265 |
+
var cur = posFromMouse(e, true);
|
266 |
+
if (cur && !posEq(cur, last)) {
|
267 |
+
if (!focused) onFocus();
|
268 |
+
last = cur;
|
269 |
+
setSelectionUser(start, cur);
|
270 |
+
updateInput = false;
|
271 |
+
var visible = visibleLines();
|
272 |
+
if (cur.line >= visible.to || cur.line < visible.from)
|
273 |
+
going = setTimeout(operation(function(){extend(e);}), 150);
|
274 |
+
}
|
275 |
+
}
|
276 |
+
|
277 |
+
var move = connect(targetDocument, "mousemove", operation(function(e) {
|
278 |
+
clearTimeout(going);
|
279 |
+
e_preventDefault(e);
|
280 |
+
extend(e);
|
281 |
+
}), true);
|
282 |
+
var up = connect(targetDocument, "mouseup", operation(function(e) {
|
283 |
+
clearTimeout(going);
|
284 |
+
var cur = posFromMouse(e);
|
285 |
+
if (cur) setSelectionUser(start, cur);
|
286 |
+
e_preventDefault(e);
|
287 |
+
end();
|
288 |
+
}), true);
|
289 |
+
}
|
290 |
+
function onDblClick(e) {
|
291 |
+
var pos = posFromMouse(e);
|
292 |
+
if (!pos) return;
|
293 |
+
selectWordAt(pos);
|
294 |
+
e_preventDefault(e);
|
295 |
+
lastDoubleClick = +new Date;
|
296 |
+
}
|
297 |
+
function onDrop(e) {
|
298 |
+
e.preventDefault();
|
299 |
+
var pos = posFromMouse(e, true), files = e.dataTransfer.files;
|
300 |
+
if (!pos || options.readOnly) return;
|
301 |
+
if (files && files.length && window.FileReader && window.File) {
|
302 |
+
function loadFile(file, i) {
|
303 |
+
var reader = new FileReader;
|
304 |
+
reader.onload = function() {
|
305 |
+
text[i] = reader.result;
|
306 |
+
if (++read == n) replaceRange(text.join(""), clipPos(pos), clipPos(pos));
|
307 |
+
};
|
308 |
+
reader.readAsText(file);
|
309 |
+
}
|
310 |
+
var n = files.length, text = Array(n), read = 0;
|
311 |
+
for (var i = 0; i < n; ++i) loadFile(files[i], i);
|
312 |
+
}
|
313 |
+
else {
|
314 |
+
try {
|
315 |
+
var text = e.dataTransfer.getData("Text");
|
316 |
+
if (text) replaceRange(text, pos, pos);
|
317 |
+
}
|
318 |
+
catch(e){}
|
319 |
+
}
|
320 |
+
}
|
321 |
+
function onKeyDown(e) {
|
322 |
+
if (!focused) onFocus();
|
323 |
+
|
324 |
+
var code = e.keyCode;
|
325 |
+
// IE does strange things with escape.
|
326 |
+
if (ie && code == 27) { e.returnValue = false; }
|
327 |
+
// Tries to detect ctrl on non-mac, cmd on mac.
|
328 |
+
var mod = (mac ? e.metaKey : e.ctrlKey) && !e.altKey, anyMod = e.ctrlKey || e.altKey || e.metaKey;
|
329 |
+
if (code == 16 || e.shiftKey) shiftSelecting = shiftSelecting || (sel.inverted ? sel.to : sel.from);
|
330 |
+
else shiftSelecting = null;
|
331 |
+
// First give onKeyEvent option a chance to handle this.
|
332 |
+
if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
|
333 |
+
|
334 |
+
if (code == 33 || code == 34) {scrollPage(code == 34); return e_preventDefault(e);} // page up/down
|
335 |
+
if (mod && ((code == 36 || code == 35) || // ctrl-home/end
|
336 |
+
mac && (code == 38 || code == 40))) { // cmd-up/down
|
337 |
+
scrollEnd(code == 36 || code == 38); return e_preventDefault(e);
|
338 |
+
}
|
339 |
+
if (mod && code == 65) {selectAll(); return e_preventDefault(e);} // ctrl-a
|
340 |
+
if (!options.readOnly) {
|
341 |
+
if (!anyMod && code == 13) {return;} // enter
|
342 |
+
if (!anyMod && code == 9 && handleTab(e.shiftKey)) return e_preventDefault(e); // tab
|
343 |
+
if (mod && code == 90) {undo(); return e_preventDefault(e);} // ctrl-z
|
344 |
+
if (mod && ((e.shiftKey && code == 90) || code == 89)) {redo(); return e_preventDefault(e);} // ctrl-shift-z, ctrl-y
|
345 |
+
}
|
346 |
+
if (code == 36) { if (options.smartHome) { smartHome(); return e_preventDefault(e); } }
|
347 |
+
|
348 |
+
// Key id to use in the movementKeys map. We also pass it to
|
349 |
+
// fastPoll in order to 'self learn'. We need this because
|
350 |
+
// reducedSelection, the hack where we collapse the selection to
|
351 |
+
// its start when it is inverted and a movement key is pressed
|
352 |
+
// (and later restore it again), shouldn't be used for
|
353 |
+
// non-movement keys.
|
354 |
+
curKeyId = (mod ? "c" : "") + (e.altKey ? "a" : "") + code;
|
355 |
+
if (sel.inverted && movementKeys[curKeyId] === true) {
|
356 |
+
var range = selRange(input);
|
357 |
+
if (range) {
|
358 |
+
reducedSelection = {anchor: range.start};
|
359 |
+
setSelRange(input, range.start, range.start);
|
360 |
+
}
|
361 |
+
}
|
362 |
+
// Don't save the key as a movementkey unless it had a modifier
|
363 |
+
if (!mod && !e.altKey) curKeyId = null;
|
364 |
+
fastPoll(curKeyId);
|
365 |
+
}
|
366 |
+
function onKeyUp(e) {
|
367 |
+
if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
|
368 |
+
if (reducedSelection) {
|
369 |
+
reducedSelection = null;
|
370 |
+
updateInput = true;
|
371 |
+
}
|
372 |
+
if (e.keyCode == 16) shiftSelecting = null;
|
373 |
+
}
|
374 |
+
function onKeyPress(e) {
|
375 |
+
if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
|
376 |
+
if (options.electricChars && mode.electricChars) {
|
377 |
+
var ch = String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode);
|
378 |
+
if (mode.electricChars.indexOf(ch) > -1)
|
379 |
+
setTimeout(operation(function() {indentLine(sel.to.line, "smart");}), 50);
|
380 |
+
}
|
381 |
+
var code = e.keyCode;
|
382 |
+
// Re-stop tab and enter. Necessary on some browsers.
|
383 |
+
if (code == 13) {if (!options.readOnly) handleEnter(); e_preventDefault(e);}
|
384 |
+
else if (!e.ctrlKey && !e.altKey && !e.metaKey && code == 9 && options.tabMode != "default") e_preventDefault(e);
|
385 |
+
else fastPoll(curKeyId);
|
386 |
+
}
|
387 |
+
|
388 |
+
function onFocus() {
|
389 |
+
if (options.readOnly == "nocursor") return;
|
390 |
+
if (!focused) {
|
391 |
+
if (options.onFocus) options.onFocus(instance);
|
392 |
+
focused = true;
|
393 |
+
if (wrapper.className.search(/\bCodeMirror-focused\b/) == -1)
|
394 |
+
wrapper.className += " CodeMirror-focused";
|
395 |
+
if (!leaveInputAlone) prepareInput();
|
396 |
+
}
|
397 |
+
slowPoll();
|
398 |
+
restartBlink();
|
399 |
+
}
|
400 |
+
function onBlur() {
|
401 |
+
if (focused) {
|
402 |
+
if (options.onBlur) options.onBlur(instance);
|
403 |
+
focused = false;
|
404 |
+
wrapper.className = wrapper.className.replace(" CodeMirror-focused", "");
|
405 |
+
}
|
406 |
+
clearInterval(blinker);
|
407 |
+
setTimeout(function() {if (!focused) shiftSelecting = null;}, 150);
|
408 |
+
}
|
409 |
+
|
410 |
+
// Replace the range from from to to by the strings in newText.
|
411 |
+
// Afterwards, set the selection to selFrom, selTo.
|
412 |
+
function updateLines(from, to, newText, selFrom, selTo) {
|
413 |
+
if (history) {
|
414 |
+
var old = [];
|
415 |
+
for (var i = from.line, e = to.line + 1; i < e; ++i) old.push(lines[i].text);
|
416 |
+
history.addChange(from.line, newText.length, old);
|
417 |
+
while (history.done.length > options.undoDepth) history.done.shift();
|
418 |
+
}
|
419 |
+
updateLinesNoUndo(from, to, newText, selFrom, selTo);
|
420 |
+
}
|
421 |
+
function unredoHelper(from, to) {
|
422 |
+
var change = from.pop();
|
423 |
+
if (change) {
|
424 |
+
var replaced = [], end = change.start + change.added;
|
425 |
+
for (var i = change.start; i < end; ++i) replaced.push(lines[i].text);
|
426 |
+
to.push({start: change.start, added: change.old.length, old: replaced});
|
427 |
+
var pos = clipPos({line: change.start + change.old.length - 1,
|
428 |
+
ch: editEnd(replaced[replaced.length-1], change.old[change.old.length-1])});
|
429 |
+
updateLinesNoUndo({line: change.start, ch: 0}, {line: end - 1, ch: lines[end-1].text.length}, change.old, pos, pos);
|
430 |
+
updateInput = true;
|
431 |
+
}
|
432 |
+
}
|
433 |
+
function undo() {unredoHelper(history.done, history.undone);}
|
434 |
+
function redo() {unredoHelper(history.undone, history.done);}
|
435 |
+
|
436 |
+
function updateLinesNoUndo(from, to, newText, selFrom, selTo) {
|
437 |
+
var recomputeMaxLength = false, maxLineLength = maxLine.length;
|
438 |
+
for (var i = from.line; i <= to.line; ++i) {
|
439 |
+
if (lines[i].text.length == maxLineLength) {recomputeMaxLength = true; break;}
|
440 |
+
}
|
441 |
+
|
442 |
+
var nlines = to.line - from.line, firstLine = lines[from.line], lastLine = lines[to.line];
|
443 |
+
// First adjust the line structure, taking some care to leave highlighting intact.
|
444 |
+
if (firstLine == lastLine) {
|
445 |
+
if (newText.length == 1)
|
446 |
+
firstLine.replace(from.ch, to.ch, newText[0]);
|
447 |
+
else {
|
448 |
+
lastLine = firstLine.split(to.ch, newText[newText.length-1]);
|
449 |
+
var spliceargs = [from.line + 1, nlines];
|
450 |
+
firstLine.replace(from.ch, firstLine.text.length, newText[0]);
|
451 |
+
for (var i = 1, e = newText.length - 1; i < e; ++i) spliceargs.push(new Line(newText[i]));
|
452 |
+
spliceargs.push(lastLine);
|
453 |
+
lines.splice.apply(lines, spliceargs);
|
454 |
+
}
|
455 |
+
}
|
456 |
+
else if (newText.length == 1) {
|
457 |
+
firstLine.replace(from.ch, firstLine.text.length, newText[0] + lastLine.text.slice(to.ch));
|
458 |
+
lines.splice(from.line + 1, nlines);
|
459 |
+
}
|
460 |
+
else {
|
461 |
+
var spliceargs = [from.line + 1, nlines - 1];
|
462 |
+
firstLine.replace(from.ch, firstLine.text.length, newText[0]);
|
463 |
+
lastLine.replace(0, to.ch, newText[newText.length-1]);
|
464 |
+
for (var i = 1, e = newText.length - 1; i < e; ++i) spliceargs.push(new Line(newText[i]));
|
465 |
+
lines.splice.apply(lines, spliceargs);
|
466 |
+
}
|
467 |
+
|
468 |
+
|
469 |
+
for (var i = from.line, e = i + newText.length; i < e; ++i) {
|
470 |
+
var l = lines[i].text;
|
471 |
+
if (l.length > maxLineLength) {
|
472 |
+
maxLine = l; maxLineLength = l.length; maxWidth = null;
|
473 |
+
recomputeMaxLength = false;
|
474 |
+
}
|
475 |
+
}
|
476 |
+
if (recomputeMaxLength) {
|
477 |
+
maxLineLength = 0; maxLine = ""; maxWidth = null;
|
478 |
+
for (var i = 0, e = lines.length; i < e; ++i) {
|
479 |
+
var l = lines[i].text;
|
480 |
+
if (l.length > maxLineLength) {
|
481 |
+
maxLineLength = l.length; maxLine = l;
|
482 |
+
}
|
483 |
+
}
|
484 |
+
}
|
485 |
+
|
486 |
+
// Add these lines to the work array, so that they will be
|
487 |
+
// highlighted. Adjust work lines if lines were added/removed.
|
488 |
+
var newWork = [], lendiff = newText.length - nlines - 1;
|
489 |
+
for (var i = 0, l = work.length; i < l; ++i) {
|
490 |
+
var task = work[i];
|
491 |
+
if (task < from.line) newWork.push(task);
|
492 |
+
else if (task > to.line) newWork.push(task + lendiff);
|
493 |
+
}
|
494 |
+
if (newText.length < 5) {
|
495 |
+
highlightLines(from.line, from.line + newText.length);
|
496 |
+
newWork.push(from.line + newText.length);
|
497 |
+
} else {
|
498 |
+
newWork.push(from.line);
|
499 |
+
}
|
500 |
+
work = newWork;
|
501 |
+
startWorker(100);
|
502 |
+
// Remember that these lines changed, for updating the display
|
503 |
+
changes.push({from: from.line, to: to.line + 1, diff: lendiff});
|
504 |
+
textChanged = {from: from, to: to, text: newText};
|
505 |
+
|
506 |
+
// Update the selection
|
507 |
+
function updateLine(n) {return n <= Math.min(to.line, to.line + lendiff) ? n : n + lendiff;}
|
508 |
+
setSelection(selFrom, selTo, updateLine(sel.from.line), updateLine(sel.to.line));
|
509 |
+
|
510 |
+
// Make sure the scroll-size div has the correct height.
|
511 |
+
code.style.height = (lines.length * lineHeight() + 2 * paddingTop()) + "px";
|
512 |
+
}
|
513 |
+
|
514 |
+
function replaceRange(code, from, to) {
|
515 |
+
from = clipPos(from);
|
516 |
+
if (!to) to = from; else to = clipPos(to);
|
517 |
+
code = splitLines(code);
|
518 |
+
function adjustPos(pos) {
|
519 |
+
if (posLess(pos, from)) return pos;
|
520 |
+
if (!posLess(to, pos)) return end;
|
521 |
+
var line = pos.line + code.length - (to.line - from.line) - 1;
|
522 |
+
var ch = pos.ch;
|
523 |
+
if (pos.line == to.line)
|
524 |
+
ch += code[code.length-1].length - (to.ch - (to.line == from.line ? from.ch : 0));
|
525 |
+
return {line: line, ch: ch};
|
526 |
+
}
|
527 |
+
var end;
|
528 |
+
replaceRange1(code, from, to, function(end1) {
|
529 |
+
end = end1;
|
530 |
+
return {from: adjustPos(sel.from), to: adjustPos(sel.to)};
|
531 |
+
});
|
532 |
+
return end;
|
533 |
+
}
|
534 |
+
function replaceSelection(code, collapse) {
|
535 |
+
replaceRange1(splitLines(code), sel.from, sel.to, function(end) {
|
536 |
+
if (collapse == "end") return {from: end, to: end};
|
537 |
+
else if (collapse == "start") return {from: sel.from, to: sel.from};
|
538 |
+
else return {from: sel.from, to: end};
|
539 |
+
});
|
540 |
+
}
|
541 |
+
function replaceRange1(code, from, to, computeSel) {
|
542 |
+
var endch = code.length == 1 ? code[0].length + from.ch : code[code.length-1].length;
|
543 |
+
var newSel = computeSel({line: from.line + code.length - 1, ch: endch});
|
544 |
+
updateLines(from, to, code, newSel.from, newSel.to);
|
545 |
+
}
|
546 |
+
|
547 |
+
function getRange(from, to) {
|
548 |
+
var l1 = from.line, l2 = to.line;
|
549 |
+
if (l1 == l2) return lines[l1].text.slice(from.ch, to.ch);
|
550 |
+
var code = [lines[l1].text.slice(from.ch)];
|
551 |
+
for (var i = l1 + 1; i < l2; ++i) code.push(lines[i].text);
|
552 |
+
code.push(lines[l2].text.slice(0, to.ch));
|
553 |
+
return code.join("\n");
|
554 |
+
}
|
555 |
+
function getSelection() {
|
556 |
+
return getRange(sel.from, sel.to);
|
557 |
+
}
|
558 |
+
|
559 |
+
var pollingFast = false; // Ensures slowPoll doesn't cancel fastPoll
|
560 |
+
function slowPoll() {
|
561 |
+
if (pollingFast) return;
|
562 |
+
poll.set(2000, function() {
|
563 |
+
startOperation();
|
564 |
+
readInput();
|
565 |
+
if (focused) slowPoll();
|
566 |
+
endOperation();
|
567 |
+
});
|
568 |
+
}
|
569 |
+
function fastPoll(keyId) {
|
570 |
+
var missed = false;
|
571 |
+
pollingFast = true;
|
572 |
+
function p() {
|
573 |
+
startOperation();
|
574 |
+
var changed = readInput();
|
575 |
+
if (changed && keyId) {
|
576 |
+
if (changed == "moved" && movementKeys[keyId] == null) movementKeys[keyId] = true;
|
577 |
+
if (changed == "changed") movementKeys[keyId] = false;
|
578 |
+
}
|
579 |
+
if (!changed && !missed) {missed = true; poll.set(80, p);}
|
580 |
+
else {pollingFast = false; slowPoll();}
|
581 |
+
endOperation();
|
582 |
+
}
|
583 |
+
poll.set(20, p);
|
584 |
+
}
|
585 |
+
|
586 |
+
// Inspects the textarea, compares its state (content, selection)
|
587 |
+
// to the data in the editing variable, and updates the editor
|
588 |
+
// content or cursor if something changed.
|
589 |
+
function readInput() {
|
590 |
+
if (leaveInputAlone || !focused) return;
|
591 |
+
var changed = false, text = input.value, sr = selRange(input);
|
592 |
+
if (!sr) return false;
|
593 |
+
var changed = editing.text != text, rs = reducedSelection;
|
594 |
+
var moved = changed || sr.start != editing.start || sr.end != (rs ? editing.start : editing.end);
|
595 |
+
if (!moved && !rs) return false;
|
596 |
+
if (changed) {
|
597 |
+
shiftSelecting = reducedSelection = null;
|
598 |
+
if (options.readOnly) {updateInput = true; return "changed";}
|
599 |
+
}
|
600 |
+
|
601 |
+
// Compute selection start and end based on start/end offsets in textarea
|
602 |
+
function computeOffset(n, startLine) {
|
603 |
+
var pos = 0;
|
604 |
+
for (;;) {
|
605 |
+
var found = text.indexOf("\n", pos);
|
606 |
+
if (found == -1 || (text.charAt(found-1) == "\r" ? found - 1 : found) >= n)
|
607 |
+
return {line: startLine, ch: n - pos};
|
608 |
+
++startLine;
|
609 |
+
pos = found + 1;
|
610 |
+
}
|
611 |
+
}
|
612 |
+
var from = computeOffset(sr.start, editing.from),
|
613 |
+
to = computeOffset(sr.end, editing.from);
|
614 |
+
// Here we have to take the reducedSelection hack into account,
|
615 |
+
// so that you can, for example, press shift-up at the start of
|
616 |
+
// your selection and have the right thing happen.
|
617 |
+
if (rs) {
|
618 |
+
var head = sr.start == rs.anchor ? to : from;
|
619 |
+
var tail = shiftSelecting ? sel.to : sr.start == rs.anchor ? from : to;
|
620 |
+
if (sel.inverted = posLess(head, tail)) { from = head; to = tail; }
|
621 |
+
else { reducedSelection = null; from = tail; to = head; }
|
622 |
+
}
|
623 |
+
|
624 |
+
// In some cases (cursor on same line as before), we don't have
|
625 |
+
// to update the textarea content at all.
|
626 |
+
if (from.line == to.line && from.line == sel.from.line && from.line == sel.to.line && !shiftSelecting)
|
627 |
+
updateInput = false;
|
628 |
+
|
629 |
+
// Magic mess to extract precise edited range from the changed
|
630 |
+
// string.
|
631 |
+
if (changed) {
|
632 |
+
var start = 0, end = text.length, len = Math.min(end, editing.text.length);
|
633 |
+
var c, line = editing.from, nl = -1;
|
634 |
+
while (start < len && (c = text.charAt(start)) == editing.text.charAt(start)) {
|
635 |
+
++start;
|
636 |
+
if (c == "\n") {line++; nl = start;}
|
637 |
+
}
|
638 |
+
var ch = nl > -1 ? start - nl : start, endline = editing.to - 1, edend = editing.text.length;
|
639 |
+
for (;;) {
|
640 |
+
c = editing.text.charAt(edend);
|
641 |
+
if (text.charAt(end) != c) {++end; ++edend; break;}
|
642 |
+
if (c == "\n") endline--;
|
643 |
+
if (edend <= start || end <= start) break;
|
644 |
+
--end; --edend;
|
645 |
+
}
|
646 |
+
var nl = editing.text.lastIndexOf("\n", edend - 1), endch = nl == -1 ? edend : edend - nl - 1;
|
647 |
+
updateLines({line: line, ch: ch}, {line: endline, ch: endch}, splitLines(text.slice(start, end)), from, to);
|
648 |
+
if (line != endline || from.line != line) updateInput = true;
|
649 |
+
}
|
650 |
+
else setSelection(from, to);
|
651 |
+
|
652 |
+
editing.text = text; editing.start = sr.start; editing.end = sr.end;
|
653 |
+
return changed ? "changed" : moved ? "moved" : false;
|
654 |
+
}
|
655 |
+
|
656 |
+
// Set the textarea content and selection range to match the
|
657 |
+
// editor state.
|
658 |
+
function prepareInput() {
|
659 |
+
var text = [];
|
660 |
+
var from = Math.max(0, sel.from.line - 1), to = Math.min(lines.length, sel.to.line + 2);
|
661 |
+
for (var i = from; i < to; ++i) text.push(lines[i].text);
|
662 |
+
text = input.value = text.join(lineSep);
|
663 |
+
var startch = sel.from.ch, endch = sel.to.ch;
|
664 |
+
for (var i = from; i < sel.from.line; ++i)
|
665 |
+
startch += lineSep.length + lines[i].text.length;
|
666 |
+
for (var i = from; i < sel.to.line; ++i)
|
667 |
+
endch += lineSep.length + lines[i].text.length;
|
668 |
+
editing = {text: text, from: from, to: to, start: startch, end: endch};
|
669 |
+
setSelRange(input, startch, reducedSelection ? startch : endch);
|
670 |
+
}
|
671 |
+
function focusInput() {
|
672 |
+
if (options.readOnly != "nocursor") input.focus();
|
673 |
+
}
|
674 |
+
|
675 |
+
function scrollEditorIntoView() {
|
676 |
+
if (!cursor.getBoundingClientRect) return;
|
677 |
+
var rect = cursor.getBoundingClientRect();
|
678 |
+
var winH = window.innerHeight || document.body.offsetHeight || document.documentElement.offsetHeight;
|
679 |
+
if (rect.top < 0 || rect.bottom > winH) cursor.scrollIntoView();
|
680 |
+
}
|
681 |
+
function scrollCursorIntoView() {
|
682 |
+
var cursor = localCoords(sel.inverted ? sel.from : sel.to);
|
683 |
+
return scrollIntoView(cursor.x, cursor.y, cursor.x, cursor.yBot);
|
684 |
+
}
|
685 |
+
function scrollIntoView(x1, y1, x2, y2) {
|
686 |
+
var pl = paddingLeft(), pt = paddingTop(), lh = lineHeight();
|
687 |
+
y1 += pt; y2 += pt; x1 += pl; x2 += pl;
|
688 |
+
var screen = scroller.clientHeight, screentop = scroller.scrollTop, scrolled = false, result = true;
|
689 |
+
if (y1 < screentop) {scroller.scrollTop = Math.max(0, y1 - 2*lh); scrolled = true;}
|
690 |
+
else if (y2 > screentop + screen) {scroller.scrollTop = y2 + lh - screen; scrolled = true;}
|
691 |
+
|
692 |
+
var screenw = scroller.clientWidth, screenleft = scroller.scrollLeft;
|
693 |
+
if (x1 < screenleft) {
|
694 |
+
if (x1 < 50) x1 = 0;
|
695 |
+
scroller.scrollLeft = Math.max(0, x1 - 10);
|
696 |
+
scrolled = true;
|
697 |
+
}
|
698 |
+
else if (x2 > screenw + screenleft) {
|
699 |
+
scroller.scrollLeft = x2 + 10 - screenw;
|
700 |
+
scrolled = true;
|
701 |
+
if (x2 > code.clientWidth) result = false;
|
702 |
+
}
|
703 |
+
if (scrolled && options.onScroll) options.onScroll(instance);
|
704 |
+
return result;
|
705 |
+
}
|
706 |
+
|
707 |
+
function visibleLines() {
|
708 |
+
var lh = lineHeight(), top = scroller.scrollTop - paddingTop();
|
709 |
+
return {from: Math.min(lines.length, Math.max(0, Math.floor(top / lh))),
|
710 |
+
to: Math.min(lines.length, Math.ceil((top + scroller.clientHeight) / lh))};
|
711 |
+
}
|
712 |
+
// Uses a set of changes plus the current scroll position to
|
713 |
+
// determine which DOM updates have to be made, and makes the
|
714 |
+
// updates.
|
715 |
+
function updateDisplay(changes) {
|
716 |
+
if (!scroller.clientWidth) {
|
717 |
+
showingFrom = showingTo = 0;
|
718 |
+
return;
|
719 |
+
}
|
720 |
+
// First create a range of theoretically intact lines, and punch
|
721 |
+
// holes in that using the change info.
|
722 |
+
var intact = changes === true ? [] : [{from: showingFrom, to: showingTo, domStart: 0}];
|
723 |
+
for (var i = 0, l = changes.length || 0; i < l; ++i) {
|
724 |
+
var change = changes[i], intact2 = [], diff = change.diff || 0;
|
725 |
+
for (var j = 0, l2 = intact.length; j < l2; ++j) {
|
726 |
+
var range = intact[j];
|
727 |
+
if (change.to <= range.from)
|
728 |
+
intact2.push({from: range.from + diff, to: range.to + diff, domStart: range.domStart});
|
729 |
+
else if (range.to <= change.from)
|
730 |
+
intact2.push(range);
|
731 |
+
else {
|
732 |
+
if (change.from > range.from)
|
733 |
+
intact2.push({from: range.from, to: change.from, domStart: range.domStart})
|
734 |
+
if (change.to < range.to)
|
735 |
+
intact2.push({from: change.to + diff, to: range.to + diff,
|
736 |
+
domStart: range.domStart + (change.to - range.from)});
|
737 |
+
}
|
738 |
+
}
|
739 |
+
intact = intact2;
|
740 |
+
}
|
741 |
+
|
742 |
+
// Then, determine which lines we'd want to see, and which
|
743 |
+
// updates have to be made to get there.
|
744 |
+
var visible = visibleLines();
|
745 |
+
var from = Math.min(showingFrom, Math.max(visible.from - 3, 0)),
|
746 |
+
to = Math.min(lines.length, Math.max(showingTo, visible.to + 3)),
|
747 |
+
updates = [], domPos = 0, domEnd = showingTo - showingFrom, pos = from, changedLines = 0;
|
748 |
+
|
749 |
+
for (var i = 0, l = intact.length; i < l; ++i) {
|
750 |
+
var range = intact[i];
|
751 |
+
if (range.to <= from) continue;
|
752 |
+
if (range.from >= to) break;
|
753 |
+
if (range.domStart > domPos || range.from > pos) {
|
754 |
+
updates.push({from: pos, to: range.from, domSize: range.domStart - domPos, domStart: domPos});
|
755 |
+
changedLines += range.from - pos;
|
756 |
+
}
|
757 |
+
pos = range.to;
|
758 |
+
domPos = range.domStart + (range.to - range.from);
|
759 |
+
}
|
760 |
+
if (domPos != domEnd || pos != to) {
|
761 |
+
changedLines += Math.abs(to - pos);
|
762 |
+
updates.push({from: pos, to: to, domSize: domEnd - domPos, domStart: domPos});
|
763 |
+
}
|
764 |
+
|
765 |
+
if (!updates.length) return;
|
766 |
+
lineDiv.style.display = "none";
|
767 |
+
// If more than 30% of the screen needs update, just do a full
|
768 |
+
// redraw (which is quicker than patching)
|
769 |
+
if (changedLines > (visible.to - visible.from) * .3)
|
770 |
+
refreshDisplay(from = Math.max(visible.from - 10, 0), to = Math.min(visible.to + 7, lines.length));
|
771 |
+
// Otherwise, only update the stuff that needs updating.
|
772 |
+
else
|
773 |
+
patchDisplay(updates);
|
774 |
+
lineDiv.style.display = "";
|
775 |
+
|
776 |
+
// Position the mover div to align with the lines it's supposed
|
777 |
+
// to be showing (which will cover the visible display)
|
778 |
+
var different = from != showingFrom || to != showingTo || lastHeight != scroller.clientHeight;
|
779 |
+
showingFrom = from; showingTo = to;
|
780 |
+
mover.style.top = (from * lineHeight()) + "px";
|
781 |
+
if (different) {
|
782 |
+
lastHeight = scroller.clientHeight;
|
783 |
+
code.style.height = (lines.length * lineHeight() + 2 * paddingTop()) + "px";
|
784 |
+
}
|
785 |
+
if (different || updates.length) updateGutter();
|
786 |
+
|
787 |
+
if (maxWidth == null) maxWidth = stringWidth(maxLine);
|
788 |
+
if (maxWidth > scroller.clientWidth) {
|
789 |
+
lineSpace.style.width = maxWidth + "px";
|
790 |
+
// Needed to prevent odd wrapping/hiding of widgets placed in here.
|
791 |
+
code.style.width = "";
|
792 |
+
code.style.width = scroller.scrollWidth + "px";
|
793 |
+
} else {
|
794 |
+
lineSpace.style.width = code.style.width = "";
|
795 |
+
}
|
796 |
+
|
797 |
+
// Since this is all rather error prone, it is honoured with the
|
798 |
+
// only assertion in the whole file.
|
799 |
+
if (lineDiv.childNodes.length != showingTo - showingFrom)
|
800 |
+
throw new Error("BAD PATCH! " + JSON.stringify(updates) + " size=" + (showingTo - showingFrom) +
|
801 |
+
" nodes=" + lineDiv.childNodes.length);
|
802 |
+
updateCursor();
|
803 |
+
}
|
804 |
+
|
805 |
+
function refreshDisplay(from, to) {
|
806 |
+
var html = [], start = {line: from, ch: 0}, inSel = posLess(sel.from, start) && !posLess(sel.to, start);
|
807 |
+
for (var i = from; i < to; ++i) {
|
808 |
+
var ch1 = null, ch2 = null;
|
809 |
+
if (inSel) {
|
810 |
+
ch1 = 0;
|
811 |
+
if (sel.to.line == i) {inSel = false; ch2 = sel.to.ch;}
|
812 |
+
}
|
813 |
+
else if (sel.from.line == i) {
|
814 |
+
if (sel.to.line == i) {ch1 = sel.from.ch; ch2 = sel.to.ch;}
|
815 |
+
else {inSel = true; ch1 = sel.from.ch;}
|
816 |
+
}
|
817 |
+
html.push(lines[i].getHTML(ch1, ch2, true));
|
818 |
+
}
|
819 |
+
lineDiv.innerHTML = html.join("");
|
820 |
+
}
|
821 |
+
function patchDisplay(updates) {
|
822 |
+
// Slightly different algorithm for IE (badInnerHTML), since
|
823 |
+
// there .innerHTML on PRE nodes is dumb, and discards
|
824 |
+
// whitespace.
|
825 |
+
var sfrom = sel.from.line, sto = sel.to.line, off = 0,
|
826 |
+
scratch = badInnerHTML && targetDocument.createElement("div");
|
827 |
+
for (var i = 0, e = updates.length; i < e; ++i) {
|
828 |
+
var rec = updates[i];
|
829 |
+
var extra = (rec.to - rec.from) - rec.domSize;
|
830 |
+
var nodeAfter = lineDiv.childNodes[rec.domStart + rec.domSize + off] || null;
|
831 |
+
if (badInnerHTML)
|
832 |
+
for (var j = Math.max(-extra, rec.domSize); j > 0; --j)
|
833 |
+
lineDiv.removeChild(nodeAfter ? nodeAfter.previousSibling : lineDiv.lastChild);
|
834 |
+
else if (extra) {
|
835 |
+
for (var j = Math.max(0, extra); j > 0; --j)
|
836 |
+
lineDiv.insertBefore(targetDocument.createElement("pre"), nodeAfter);
|
837 |
+
for (var j = Math.max(0, -extra); j > 0; --j)
|
838 |
+
lineDiv.removeChild(nodeAfter ? nodeAfter.previousSibling : lineDiv.lastChild);
|
839 |
+
}
|
840 |
+
var node = lineDiv.childNodes[rec.domStart + off], inSel = sfrom < rec.from && sto >= rec.from;
|
841 |
+
for (var j = rec.from; j < rec.to; ++j) {
|
842 |
+
var ch1 = null, ch2 = null;
|
843 |
+
if (inSel) {
|
844 |
+
ch1 = 0;
|
845 |
+
if (sto == j) {inSel = false; ch2 = sel.to.ch;}
|
846 |
+
}
|
847 |
+
else if (sfrom == j) {
|
848 |
+
if (sto == j) {ch1 = sel.from.ch; ch2 = sel.to.ch;}
|
849 |
+
else {inSel = true; ch1 = sel.from.ch;}
|
850 |
+
}
|
851 |
+
if (badInnerHTML) {
|
852 |
+
scratch.innerHTML = lines[j].getHTML(ch1, ch2, true);
|
853 |
+
lineDiv.insertBefore(scratch.firstChild, nodeAfter);
|
854 |
+
}
|
855 |
+
else {
|
856 |
+
node.innerHTML = lines[j].getHTML(ch1, ch2, false);
|
857 |
+
node.className = lines[j].className || "";
|
858 |
+
node = node.nextSibling;
|
859 |
+
}
|
860 |
+
}
|
861 |
+
off += extra;
|
862 |
+
}
|
863 |
+
}
|
864 |
+
|
865 |
+
function updateGutter() {
|
866 |
+
if (!options.gutter && !options.lineNumbers) return;
|
867 |
+
var hText = mover.offsetHeight, hEditor = scroller.clientHeight;
|
868 |
+
gutter.style.height = (hText - hEditor < 2 ? hEditor : hText) + "px";
|
869 |
+
var html = [];
|
870 |
+
for (var i = showingFrom; i < Math.max(showingTo, showingFrom + 1); ++i) {
|
871 |
+
var marker = lines[i].gutterMarker;
|
872 |
+
var text = options.lineNumbers ? i + options.firstLineNumber : null;
|
873 |
+
if (marker && marker.text)
|
874 |
+
text = marker.text.replace("%N%", text != null ? text : "");
|
875 |
+
else if (text == null)
|
876 |
+
text = "\u00a0";
|
877 |
+
html.push((marker && marker.style ? '<pre class="' + marker.style + '">' : "<pre>"), text, "</pre>");
|
878 |
+
}
|
879 |
+
gutter.style.display = "none";
|
880 |
+
gutterText.innerHTML = html.join("");
|
881 |
+
var minwidth = String(lines.length).length, firstNode = gutterText.firstChild, val = eltText(firstNode), pad = "";
|
882 |
+
while (val.length + pad.length < minwidth) pad += "\u00a0";
|
883 |
+
if (pad) firstNode.insertBefore(targetDocument.createTextNode(pad), firstNode.firstChild);
|
884 |
+
gutter.style.display = "";
|
885 |
+
lineSpace.style.marginLeft = gutter.offsetWidth + "px";
|
886 |
+
}
|
887 |
+
function updateCursor() {
|
888 |
+
var head = sel.inverted ? sel.from : sel.to, lh = lineHeight();
|
889 |
+
var x = charX(head.line, head.ch);
|
890 |
+
inputDiv.style.top = (head.line * lh - scroller.scrollTop) + "px";
|
891 |
+
inputDiv.style.left = (x - scroller.scrollLeft) + "px";
|
892 |
+
if (posEq(sel.from, sel.to)) {
|
893 |
+
cursor.style.top = (head.line - showingFrom) * lh + "px";
|
894 |
+
cursor.style.left = x + "px";
|
895 |
+
cursor.style.display = "";
|
896 |
+
}
|
897 |
+
else cursor.style.display = "none";
|
898 |
+
}
|
899 |
+
|
900 |
+
function setSelectionUser(from, to) {
|
901 |
+
var sh = shiftSelecting && clipPos(shiftSelecting);
|
902 |
+
if (sh) {
|
903 |
+
if (posLess(sh, from)) from = sh;
|
904 |
+
else if (posLess(to, sh)) to = sh;
|
905 |
+
}
|
906 |
+
setSelection(from, to);
|
907 |
+
}
|
908 |
+
// Update the selection. Last two args are only used by
|
909 |
+
// updateLines, since they have to be expressed in the line
|
910 |
+
// numbers before the update.
|
911 |
+
function setSelection(from, to, oldFrom, oldTo) {
|
912 |
+
if (posEq(sel.from, from) && posEq(sel.to, to)) return;
|
913 |
+
if (posLess(to, from)) {var tmp = to; to = from; from = tmp;}
|
914 |
+
|
915 |
+
if (posEq(from, to)) sel.inverted = false;
|
916 |
+
else if (posEq(from, sel.to)) sel.inverted = false;
|
917 |
+
else if (posEq(to, sel.from)) sel.inverted = true;
|
918 |
+
|
919 |
+
// Some ugly logic used to only mark the lines that actually did
|
920 |
+
// see a change in selection as changed, rather than the whole
|
921 |
+
// selected range.
|
922 |
+
if (oldFrom == null) {oldFrom = sel.from.line; oldTo = sel.to.line;}
|
923 |
+
if (posEq(from, to)) {
|
924 |
+
if (!posEq(sel.from, sel.to))
|
925 |
+
changes.push({from: oldFrom, to: oldTo + 1});
|
926 |
+
}
|
927 |
+
else if (posEq(sel.from, sel.to)) {
|
928 |
+
changes.push({from: from.line, to: to.line + 1});
|
929 |
+
}
|
930 |
+
else {
|
931 |
+
if (!posEq(from, sel.from)) {
|
932 |
+
if (from.line < oldFrom)
|
933 |
+
changes.push({from: from.line, to: Math.min(to.line, oldFrom) + 1});
|
934 |
+
else
|
935 |
+
changes.push({from: oldFrom, to: Math.min(oldTo, from.line) + 1});
|
936 |
+
}
|
937 |
+
if (!posEq(to, sel.to)) {
|
938 |
+
if (to.line < oldTo)
|
939 |
+
changes.push({from: Math.max(oldFrom, from.line), to: oldTo + 1});
|
940 |
+
else
|
941 |
+
changes.push({from: Math.max(from.line, oldTo), to: to.line + 1});
|
942 |
+
}
|
943 |
+
}
|
944 |
+
sel.from = from; sel.to = to;
|
945 |
+
selectionChanged = true;
|
946 |
+
}
|
947 |
+
function setCursor(line, ch, user) {
|
948 |
+
var pos = clipPos({line: line, ch: ch || 0});
|
949 |
+
(user ? setSelectionUser : setSelection)(pos, pos);
|
950 |
+
}
|
951 |
+
|
952 |
+
function clipLine(n) {return Math.max(0, Math.min(n, lines.length-1));}
|
953 |
+
function clipPos(pos) {
|
954 |
+
if (pos.line < 0) return {line: 0, ch: 0};
|
955 |
+
if (pos.line >= lines.length) return {line: lines.length-1, ch: lines[lines.length-1].text.length};
|
956 |
+
var ch = pos.ch, linelen = lines[pos.line].text.length;
|
957 |
+
if (ch == null || ch > linelen) return {line: pos.line, ch: linelen};
|
958 |
+
else if (ch < 0) return {line: pos.line, ch: 0};
|
959 |
+
else return pos;
|
960 |
+
}
|
961 |
+
|
962 |
+
function scrollPage(down) {
|
963 |
+
var linesPerPage = Math.floor(scroller.clientHeight / lineHeight()), head = sel.inverted ? sel.from : sel.to;
|
964 |
+
setCursor(head.line + (Math.max(linesPerPage - 1, 1) * (down ? 1 : -1)), head.ch, true);
|
965 |
+
}
|
966 |
+
function scrollEnd(top) {
|
967 |
+
var pos = top ? {line: 0, ch: 0} : {line: lines.length - 1, ch: lines[lines.length-1].text.length};
|
968 |
+
setSelectionUser(pos, pos);
|
969 |
+
}
|
970 |
+
function selectAll() {
|
971 |
+
var endLine = lines.length - 1;
|
972 |
+
setSelection({line: 0, ch: 0}, {line: endLine, ch: lines[endLine].text.length});
|
973 |
+
}
|
974 |
+
function selectWordAt(pos) {
|
975 |
+
var line = lines[pos.line].text;
|
976 |
+
var start = pos.ch, end = pos.ch;
|
977 |
+
while (start > 0 && /\w/.test(line.charAt(start - 1))) --start;
|
978 |
+
while (end < line.length && /\w/.test(line.charAt(end))) ++end;
|
979 |
+
setSelectionUser({line: pos.line, ch: start}, {line: pos.line, ch: end});
|
980 |
+
}
|
981 |
+
function selectLine(line) {
|
982 |
+
setSelectionUser({line: line, ch: 0}, {line: line, ch: lines[line].text.length});
|
983 |
+
}
|
984 |
+
function handleEnter() {
|
985 |
+
replaceSelection("\n", "end");
|
986 |
+
if (options.enterMode != "flat")
|
987 |
+
indentLine(sel.from.line, options.enterMode == "keep" ? "prev" : "smart");
|
988 |
+
}
|
989 |
+
function handleTab(shift) {
|
990 |
+
function indentSelected(mode) {
|
991 |
+
if (posEq(sel.from, sel.to)) return indentLine(sel.from.line, mode);
|
992 |
+
var e = sel.to.line - (sel.to.ch ? 0 : 1);
|
993 |
+
for (var i = sel.from.line; i <= e; ++i) indentLine(i, mode);
|
994 |
+
}
|
995 |
+
shiftSelecting = null;
|
996 |
+
switch (options.tabMode) {
|
997 |
+
case "default":
|
998 |
+
return false;
|
999 |
+
case "indent":
|
1000 |
+
indentSelected("smart");
|
1001 |
+
break;
|
1002 |
+
case "classic":
|
1003 |
+
if (posEq(sel.from, sel.to)) {
|
1004 |
+
if (shift) indentLine(sel.from.line, "smart");
|
1005 |
+
else replaceSelection("\t", "end");
|
1006 |
+
break;
|
1007 |
+
}
|
1008 |
+
case "shift":
|
1009 |
+
indentSelected(shift ? "subtract" : "add");
|
1010 |
+
break;
|
1011 |
+
}
|
1012 |
+
return true;
|
1013 |
+
}
|
1014 |
+
function smartHome() {
|
1015 |
+
var firstNonWS = Math.max(0, lines[sel.from.line].text.search(/\S/));
|
1016 |
+
setCursor(sel.from.line, sel.from.ch <= firstNonWS && sel.from.ch ? 0 : firstNonWS, true);
|
1017 |
+
}
|
1018 |
+
|
1019 |
+
function indentLine(n, how) {
|
1020 |
+
if (how == "smart") {
|
1021 |
+
if (!mode.indent) how = "prev";
|
1022 |
+
else var state = getStateBefore(n);
|
1023 |
+
}
|
1024 |
+
|
1025 |
+
var line = lines[n], curSpace = line.indentation(), curSpaceString = line.text.match(/^\s*/)[0], indentation;
|
1026 |
+
if (how == "prev") {
|
1027 |
+
if (n) indentation = lines[n-1].indentation();
|
1028 |
+
else indentation = 0;
|
1029 |
+
}
|
1030 |
+
else if (how == "smart") indentation = mode.indent(state, line.text.slice(curSpaceString.length));
|
1031 |
+
else if (how == "add") indentation = curSpace + options.indentUnit;
|
1032 |
+
else if (how == "subtract") indentation = curSpace - options.indentUnit;
|
1033 |
+
indentation = Math.max(0, indentation);
|
1034 |
+
var diff = indentation - curSpace;
|
1035 |
+
|
1036 |
+
if (!diff) {
|
1037 |
+
if (sel.from.line != n && sel.to.line != n) return;
|
1038 |
+
var indentString = curSpaceString;
|
1039 |
+
}
|
1040 |
+
else {
|
1041 |
+
var indentString = "", pos = 0;
|
1042 |
+
if (options.indentWithTabs)
|
1043 |
+
for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";}
|
1044 |
+
while (pos < indentation) {++pos; indentString += " ";}
|
1045 |
+
}
|
1046 |
+
|
1047 |
+
replaceRange(indentString, {line: n, ch: 0}, {line: n, ch: curSpaceString.length});
|
1048 |
+
}
|
1049 |
+
|
1050 |
+
function loadMode() {
|
1051 |
+
mode = CodeMirror.getMode(options, options.mode);
|
1052 |
+
for (var i = 0, l = lines.length; i < l; ++i)
|
1053 |
+
lines[i].stateAfter = null;
|
1054 |
+
work = [0];
|
1055 |
+
startWorker();
|
1056 |
+
}
|
1057 |
+
function gutterChanged() {
|
1058 |
+
var visible = options.gutter || options.lineNumbers;
|
1059 |
+
gutter.style.display = visible ? "" : "none";
|
1060 |
+
if (visible) updateGutter();
|
1061 |
+
else lineDiv.parentNode.style.marginLeft = 0;
|
1062 |
+
}
|
1063 |
+
|
1064 |
+
function markText(from, to, className) {
|
1065 |
+
from = clipPos(from); to = clipPos(to);
|
1066 |
+
var accum = [];
|
1067 |
+
function add(line, from, to, className) {
|
1068 |
+
var line = lines[line], mark = line.addMark(from, to, className);
|
1069 |
+
mark.line = line;
|
1070 |
+
accum.push(mark);
|
1071 |
+
}
|
1072 |
+
if (from.line == to.line) add(from.line, from.ch, to.ch, className);
|
1073 |
+
else {
|
1074 |
+
add(from.line, from.ch, null, className);
|
1075 |
+
for (var i = from.line + 1, e = to.line; i < e; ++i)
|
1076 |
+
add(i, 0, null, className);
|
1077 |
+
add(to.line, 0, to.ch, className);
|
1078 |
+
}
|
1079 |
+
changes.push({from: from.line, to: to.line + 1});
|
1080 |
+
return function() {
|
1081 |
+
var start, end;
|
1082 |
+
for (var i = 0; i < accum.length; ++i) {
|
1083 |
+
var mark = accum[i], found = indexOf(lines, mark.line);
|
1084 |
+
mark.line.removeMark(mark);
|
1085 |
+
if (found > -1) {
|
1086 |
+
if (start == null) start = found;
|
1087 |
+
end = found;
|
1088 |
+
}
|
1089 |
+
}
|
1090 |
+
if (start != null) changes.push({from: start, to: end + 1});
|
1091 |
+
};
|
1092 |
+
}
|
1093 |
+
|
1094 |
+
function addGutterMarker(line, text, className) {
|
1095 |
+
if (typeof line == "number") line = lines[clipLine(line)];
|
1096 |
+
line.gutterMarker = {text: text, style: className};
|
1097 |
+
updateGutter();
|
1098 |
+
return line;
|
1099 |
+
}
|
1100 |
+
function removeGutterMarker(line) {
|
1101 |
+
if (typeof line == "number") line = lines[clipLine(line)];
|
1102 |
+
line.gutterMarker = null;
|
1103 |
+
updateGutter();
|
1104 |
+
}
|
1105 |
+
function setLineClass(line, className) {
|
1106 |
+
if (typeof line == "number") {
|
1107 |
+
var no = line;
|
1108 |
+
line = lines[clipLine(line)];
|
1109 |
+
}
|
1110 |
+
else {
|
1111 |
+
var no = indexOf(lines, line);
|
1112 |
+
if (no == -1) return null;
|
1113 |
+
}
|
1114 |
+
if (line.className != className) {
|
1115 |
+
line.className = className;
|
1116 |
+
changes.push({from: no, to: no + 1});
|
1117 |
+
}
|
1118 |
+
return line;
|
1119 |
+
}
|
1120 |
+
|
1121 |
+
function lineInfo(line) {
|
1122 |
+
if (typeof line == "number") {
|
1123 |
+
var n = line;
|
1124 |
+
line = lines[line];
|
1125 |
+
if (!line) return null;
|
1126 |
+
}
|
1127 |
+
else {
|
1128 |
+
var n = indexOf(lines, line);
|
1129 |
+
if (n == -1) return null;
|
1130 |
+
}
|
1131 |
+
var marker = line.gutterMarker;
|
1132 |
+
return {line: n, text: line.text, markerText: marker && marker.text, markerClass: marker && marker.style};
|
1133 |
+
}
|
1134 |
+
|
1135 |
+
function stringWidth(str) {
|
1136 |
+
measure.innerHTML = "<pre><span>x</span></pre>";
|
1137 |
+
measure.firstChild.firstChild.firstChild.nodeValue = str;
|
1138 |
+
return measure.firstChild.firstChild.offsetWidth || 10;
|
1139 |
+
}
|
1140 |
+
// These are used to go from pixel positions to character
|
1141 |
+
// positions, taking varying character widths into account.
|
1142 |
+
function charX(line, pos) {
|
1143 |
+
if (pos == 0) return 0;
|
1144 |
+
measure.innerHTML = "<pre><span>" + lines[line].getHTML(null, null, false, pos) + "</span></pre>";
|
1145 |
+
return measure.firstChild.firstChild.offsetWidth;
|
1146 |
+
}
|
1147 |
+
function charFromX(line, x) {
|
1148 |
+
if (x <= 0) return 0;
|
1149 |
+
var lineObj = lines[line], text = lineObj.text;
|
1150 |
+
function getX(len) {
|
1151 |
+
measure.innerHTML = "<pre><span>" + lineObj.getHTML(null, null, false, len) + "</span></pre>";
|
1152 |
+
return measure.firstChild.firstChild.offsetWidth;
|
1153 |
+
}
|
1154 |
+
var from = 0, fromX = 0, to = text.length, toX;
|
1155 |
+
// Guess a suitable upper bound for our search.
|
1156 |
+
var estimated = Math.min(to, Math.ceil(x / stringWidth("x")));
|
1157 |
+
for (;;) {
|
1158 |
+
var estX = getX(estimated);
|
1159 |
+
if (estX <= x && estimated < to) estimated = Math.min(to, Math.ceil(estimated * 1.2));
|
1160 |
+
else {toX = estX; to = estimated; break;}
|
1161 |
+
}
|
1162 |
+
if (x > toX) return to;
|
1163 |
+
// Try to guess a suitable lower bound as well.
|
1164 |
+
estimated = Math.floor(to * 0.8); estX = getX(estimated);
|
1165 |
+
if (estX < x) {from = estimated; fromX = estX;}
|
1166 |
+
// Do a binary search between these bounds.
|
1167 |
+
for (;;) {
|
1168 |
+
if (to - from <= 1) return (toX - x > x - fromX) ? from : to;
|
1169 |
+
var middle = Math.ceil((from + to) / 2), middleX = getX(middle);
|
1170 |
+
if (middleX > x) {to = middle; toX = middleX;}
|
1171 |
+
else {from = middle; fromX = middleX;}
|
1172 |
+
}
|
1173 |
+
}
|
1174 |
+
|
1175 |
+
function localCoords(pos, inLineWrap) {
|
1176 |
+
var lh = lineHeight(), line = pos.line - (inLineWrap ? showingFrom : 0);
|
1177 |
+
return {x: charX(pos.line, pos.ch), y: line * lh, yBot: (line + 1) * lh};
|
1178 |
+
}
|
1179 |
+
function pageCoords(pos) {
|
1180 |
+
var local = localCoords(pos, true), off = eltOffset(lineSpace);
|
1181 |
+
return {x: off.left + local.x, y: off.top + local.y, yBot: off.top + local.yBot};
|
1182 |
+
}
|
1183 |
+
|
1184 |
+
function lineHeight() {
|
1185 |
+
var nlines = lineDiv.childNodes.length;
|
1186 |
+
if (nlines) return (lineDiv.offsetHeight / nlines) || 1;
|
1187 |
+
measure.innerHTML = "<pre>x</pre>";
|
1188 |
+
return measure.firstChild.offsetHeight || 1;
|
1189 |
+
}
|
1190 |
+
function paddingTop() {return lineSpace.offsetTop;}
|
1191 |
+
function paddingLeft() {return lineSpace.offsetLeft;}
|
1192 |
+
|
1193 |
+
function posFromMouse(e, liberal) {
|
1194 |
+
var offW = eltOffset(scroller, true), x, y;
|
1195 |
+
// Fails unpredictably on IE[67] when mouse is dragged around quickly.
|
1196 |
+
try { x = e.clientX; y = e.clientY; } catch (e) { return null; }
|
1197 |
+
// This is a mess of a heuristic to try and determine whether a
|
1198 |
+
// scroll-bar was clicked or not, and to return null if one was
|
1199 |
+
// (and !liberal).
|
1200 |
+
if (!liberal && (x - offW.left > scroller.clientWidth || y - offW.top > scroller.clientHeight))
|
1201 |
+
return null;
|
1202 |
+
var offL = eltOffset(lineSpace, true);
|
1203 |
+
var line = showingFrom + Math.floor((y - offL.top) / lineHeight());
|
1204 |
+
return clipPos({line: line, ch: charFromX(clipLine(line), x - offL.left)});
|
1205 |
+
}
|
1206 |
+
function onContextMenu(e) {
|
1207 |
+
var pos = posFromMouse(e);
|
1208 |
+
if (!pos || window.opera) return; // Opera is difficult.
|
1209 |
+
if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to))
|
1210 |
+
operation(setCursor)(pos.line, pos.ch);
|
1211 |
+
|
1212 |
+
var oldCSS = input.style.cssText;
|
1213 |
+
inputDiv.style.position = "absolute";
|
1214 |
+
input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
|
1215 |
+
"px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: white; " +
|
1216 |
+
"border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
|
1217 |
+
leaveInputAlone = true;
|
1218 |
+
var val = input.value = getSelection();
|
1219 |
+
focusInput();
|
1220 |
+
setSelRange(input, 0, input.value.length);
|
1221 |
+
function rehide() {
|
1222 |
+
var newVal = splitLines(input.value).join("\n");
|
1223 |
+
if (newVal != val) operation(replaceSelection)(newVal, "end");
|
1224 |
+
inputDiv.style.position = "relative";
|
1225 |
+
input.style.cssText = oldCSS;
|
1226 |
+
leaveInputAlone = false;
|
1227 |
+
prepareInput();
|
1228 |
+
slowPoll();
|
1229 |
+
}
|
1230 |
+
|
1231 |
+
if (gecko) {
|
1232 |
+
e_stop(e);
|
1233 |
+
var mouseup = connect(window, "mouseup", function() {
|
1234 |
+
mouseup();
|
1235 |
+
setTimeout(rehide, 20);
|
1236 |
+
}, true);
|
1237 |
+
}
|
1238 |
+
else {
|
1239 |
+
setTimeout(rehide, 50);
|
1240 |
+
}
|
1241 |
+
}
|
1242 |
+
|
1243 |
+
// Cursor-blinking
|
1244 |
+
function restartBlink() {
|
1245 |
+
clearInterval(blinker);
|
1246 |
+
var on = true;
|
1247 |
+
cursor.style.visibility = "";
|
1248 |
+
blinker = setInterval(function() {
|
1249 |
+
cursor.style.visibility = (on = !on) ? "" : "hidden";
|
1250 |
+
}, 650);
|
1251 |
+
}
|
1252 |
+
|
1253 |
+
var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
|
1254 |
+
function matchBrackets(autoclear) {
|
1255 |
+
var head = sel.inverted ? sel.from : sel.to, line = lines[head.line], pos = head.ch - 1;
|
1256 |
+
var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];
|
1257 |
+
if (!match) return;
|
1258 |
+
var ch = match.charAt(0), forward = match.charAt(1) == ">", d = forward ? 1 : -1, st = line.styles;
|
1259 |
+
for (var off = pos + 1, i = 0, e = st.length; i < e; i+=2)
|
1260 |
+
if ((off -= st[i].length) <= 0) {var style = st[i+1]; break;}
|
1261 |
+
|
1262 |
+
var stack = [line.text.charAt(pos)], re = /[(){}[\]]/;
|
1263 |
+
function scan(line, from, to) {
|
1264 |
+
if (!line.text) return;
|
1265 |
+
var st = line.styles, pos = forward ? 0 : line.text.length - 1, cur;
|
1266 |
+
for (var i = forward ? 0 : st.length - 2, e = forward ? st.length : -2; i != e; i += 2*d) {
|
1267 |
+
var text = st[i];
|
1268 |
+
if (st[i+1] != null && st[i+1] != style) {pos += d * text.length; continue;}
|
1269 |
+
for (var j = forward ? 0 : text.length - 1, te = forward ? text.length : -1; j != te; j += d, pos+=d) {
|
1270 |
+
if (pos >= from && pos < to && re.test(cur = text.charAt(j))) {
|
1271 |
+
var match = matching[cur];
|
1272 |
+
if (match.charAt(1) == ">" == forward) stack.push(cur);
|
1273 |
+
else if (stack.pop() != match.charAt(0)) return {pos: pos, match: false};
|
1274 |
+
else if (!stack.length) return {pos: pos, match: true};
|
1275 |
+
}
|
1276 |
+
}
|
1277 |
+
}
|
1278 |
+
}
|
1279 |
+
for (var i = head.line, e = forward ? Math.min(i + 100, lines.length) : Math.max(-1, i - 100); i != e; i+=d) {
|
1280 |
+
var line = lines[i], first = i == head.line;
|
1281 |
+
var found = scan(line, first && forward ? pos + 1 : 0, first && !forward ? pos : line.text.length);
|
1282 |
+
if (found) break;
|
1283 |
+
}
|
1284 |
+
if (!found) found = {pos: null, match: false};
|
1285 |
+
var style = found.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
|
1286 |
+
var one = markText({line: head.line, ch: pos}, {line: head.line, ch: pos+1}, style),
|
1287 |
+
two = found.pos != null
|
1288 |
+
? markText({line: i, ch: found.pos}, {line: i, ch: found.pos + 1}, style)
|
1289 |
+
: function() {};
|
1290 |
+
var clear = operation(function(){one(); two();});
|
1291 |
+
if (autoclear) setTimeout(clear, 800);
|
1292 |
+
else bracketHighlighted = clear;
|
1293 |
+
}
|
1294 |
+
|
1295 |
+
// Finds the line to start with when starting a parse. Tries to
|
1296 |
+
// find a line with a stateAfter, so that it can start with a
|
1297 |
+
// valid state. If that fails, it returns the line with the
|
1298 |
+
// smallest indentation, which tends to need the least context to
|
1299 |
+
// parse correctly.
|
1300 |
+
function findStartLine(n) {
|
1301 |
+
var minindent, minline;
|
1302 |
+
for (var search = n, lim = n - 40; search > lim; --search) {
|
1303 |
+
if (search == 0) return 0;
|
1304 |
+
var line = lines[search-1];
|
1305 |
+
if (line.stateAfter) return search;
|
1306 |
+
var indented = line.indentation();
|
1307 |
+
if (minline == null || minindent > indented) {
|
1308 |
+
minline = search - 1;
|
1309 |
+
minindent = indented;
|
1310 |
+
}
|
1311 |
+
}
|
1312 |
+
return minline;
|
1313 |
+
}
|
1314 |
+
function getStateBefore(n) {
|
1315 |
+
var start = findStartLine(n), state = start && lines[start-1].stateAfter;
|
1316 |
+
if (!state) state = startState(mode);
|
1317 |
+
else state = copyState(mode, state);
|
1318 |
+
for (var i = start; i < n; ++i) {
|
1319 |
+
var line = lines[i];
|
1320 |
+
line.highlight(mode, state);
|
1321 |
+
line.stateAfter = copyState(mode, state);
|
1322 |
+
}
|
1323 |
+
if (n < lines.length && !lines[n].stateAfter) work.push(n);
|
1324 |
+
return state;
|
1325 |
+
}
|
1326 |
+
function highlightLines(start, end) {
|
1327 |
+
var state = getStateBefore(start);
|
1328 |
+
for (var i = start; i < end; ++i) {
|
1329 |
+
var line = lines[i];
|
1330 |
+
line.highlight(mode, state);
|
1331 |
+
line.stateAfter = copyState(mode, state);
|
1332 |
+
}
|
1333 |
+
}
|
1334 |
+
function highlightWorker() {
|
1335 |
+
var end = +new Date + options.workTime;
|
1336 |
+
var foundWork = work.length;
|
1337 |
+
while (work.length) {
|
1338 |
+
if (!lines[showingFrom].stateAfter) var task = showingFrom;
|
1339 |
+
else var task = work.pop();
|
1340 |
+
if (task >= lines.length) continue;
|
1341 |
+
var start = findStartLine(task), state = start && lines[start-1].stateAfter;
|
1342 |
+
if (state) state = copyState(mode, state);
|
1343 |
+
else state = startState(mode);
|
1344 |
+
|
1345 |
+
var unchanged = 0, compare = mode.compareStates, realChange = false;
|
1346 |
+
for (var i = start, l = lines.length; i < l; ++i) {
|
1347 |
+
var line = lines[i], hadState = line.stateAfter;
|
1348 |
+
if (+new Date > end) {
|
1349 |
+
work.push(i);
|
1350 |
+
startWorker(options.workDelay);
|
1351 |
+
if (realChange) changes.push({from: task, to: i + 1});
|
1352 |
+
return;
|
1353 |
+
}
|
1354 |
+
var changed = line.highlight(mode, state);
|
1355 |
+
if (changed) realChange = true;
|
1356 |
+
line.stateAfter = copyState(mode, state);
|
1357 |
+
if (compare) {
|
1358 |
+
if (hadState && compare(hadState, state)) break;
|
1359 |
+
} else {
|
1360 |
+
if (changed !== false || !hadState) unchanged = 0;
|
1361 |
+
else if (++unchanged > 3) break;
|
1362 |
+
}
|
1363 |
+
}
|
1364 |
+
if (realChange) changes.push({from: task, to: i + 1});
|
1365 |
+
}
|
1366 |
+
if (foundWork && options.onHighlightComplete)
|
1367 |
+
options.onHighlightComplete(instance);
|
1368 |
+
}
|
1369 |
+
function startWorker(time) {
|
1370 |
+
if (!work.length) return;
|
1371 |
+
highlight.set(time, operation(highlightWorker));
|
1372 |
+
}
|
1373 |
+
|
1374 |
+
// Operations are used to wrap changes in such a way that each
|
1375 |
+
// change won't have to update the cursor and display (which would
|
1376 |
+
// be awkward, slow, and error-prone), but instead updates are
|
1377 |
+
// batched and then all combined and executed at once.
|
1378 |
+
function startOperation() {
|
1379 |
+
updateInput = null; changes = []; textChanged = selectionChanged = false;
|
1380 |
+
}
|
1381 |
+
function endOperation() {
|
1382 |
+
var reScroll = false;
|
1383 |
+
if (selectionChanged) reScroll = !scrollCursorIntoView();
|
1384 |
+
if (changes.length) updateDisplay(changes);
|
1385 |
+
else if (selectionChanged) updateCursor();
|
1386 |
+
if (reScroll) scrollCursorIntoView();
|
1387 |
+
if (selectionChanged) {scrollEditorIntoView(); restartBlink();}
|
1388 |
+
|
1389 |
+
// updateInput can be set to a boolean value to force/prevent an
|
1390 |
+
// update.
|
1391 |
+
if (focused && !leaveInputAlone &&
|
1392 |
+
(updateInput === true || (updateInput !== false && selectionChanged)))
|
1393 |
+
prepareInput();
|
1394 |
+
|
1395 |
+
if (selectionChanged && options.matchBrackets)
|
1396 |
+
setTimeout(operation(function() {
|
1397 |
+
if (bracketHighlighted) {bracketHighlighted(); bracketHighlighted = null;}
|
1398 |
+
matchBrackets(false);
|
1399 |
+
}), 20);
|
1400 |
+
var tc = textChanged; // textChanged can be reset by cursoractivity callback
|
1401 |
+
if (selectionChanged && options.onCursorActivity)
|
1402 |
+
options.onCursorActivity(instance);
|
1403 |
+
if (tc && options.onChange && instance)
|
1404 |
+
options.onChange(instance, tc);
|
1405 |
+
}
|
1406 |
+
var nestedOperation = 0;
|
1407 |
+
function operation(f) {
|
1408 |
+
return function() {
|
1409 |
+
if (!nestedOperation++) startOperation();
|
1410 |
+
try {var result = f.apply(this, arguments);}
|
1411 |
+
finally {if (!--nestedOperation) endOperation();}
|
1412 |
+
return result;
|
1413 |
+
};
|
1414 |
+
}
|
1415 |
+
|
1416 |
+
function SearchCursor(query, pos, caseFold) {
|
1417 |
+
this.atOccurrence = false;
|
1418 |
+
if (caseFold == null) caseFold = typeof query == "string" && query == query.toLowerCase();
|
1419 |
+
|
1420 |
+
if (pos && typeof pos == "object") pos = clipPos(pos);
|
1421 |
+
else pos = {line: 0, ch: 0};
|
1422 |
+
this.pos = {from: pos, to: pos};
|
1423 |
+
|
1424 |
+
// The matches method is filled in based on the type of query.
|
1425 |
+
// It takes a position and a direction, and returns an object
|
1426 |
+
// describing the next occurrence of the query, or null if no
|
1427 |
+
// more matches were found.
|
1428 |
+
if (typeof query != "string") // Regexp match
|
1429 |
+
this.matches = function(reverse, pos) {
|
1430 |
+
if (reverse) {
|
1431 |
+
var line = lines[pos.line].text.slice(0, pos.ch), match = line.match(query), start = 0;
|
1432 |
+
while (match) {
|
1433 |
+
var ind = line.indexOf(match[0]);
|
1434 |
+
start += ind;
|
1435 |
+
line = line.slice(ind + 1);
|
1436 |
+
var newmatch = line.match(query);
|
1437 |
+
if (newmatch) match = newmatch;
|
1438 |
+
else break;
|
1439 |
+
start++;
|
1440 |
+
}
|
1441 |
+
}
|
1442 |
+
else {
|
1443 |
+
var line = lines[pos.line].text.slice(pos.ch), match = line.match(query),
|
1444 |
+
start = match && pos.ch + line.indexOf(match[0]);
|
1445 |
+
}
|
1446 |
+
if (match)
|
1447 |
+
return {from: {line: pos.line, ch: start},
|
1448 |
+
to: {line: pos.line, ch: start + match[0].length},
|
1449 |
+
match: match};
|
1450 |
+
};
|
1451 |
+
else { // String query
|
1452 |
+
if (caseFold) query = query.toLowerCase();
|
1453 |
+
var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;};
|
1454 |
+
var target = query.split("\n");
|
1455 |
+
// Different methods for single-line and multi-line queries
|
1456 |
+
if (target.length == 1)
|
1457 |
+
this.matches = function(reverse, pos) {
|
1458 |
+
var line = fold(lines[pos.line].text), len = query.length, match;
|
1459 |
+
if (reverse ? (pos.ch >= len && (match = line.lastIndexOf(query, pos.ch - len)) != -1)
|
1460 |
+
: (match = line.indexOf(query, pos.ch)) != -1)
|
1461 |
+
return {from: {line: pos.line, ch: match},
|
1462 |
+
to: {line: pos.line, ch: match + len}};
|
1463 |
+
};
|
1464 |
+
else
|
1465 |
+
this.matches = function(reverse, pos) {
|
1466 |
+
var ln = pos.line, idx = (reverse ? target.length - 1 : 0), match = target[idx], line = fold(lines[ln].text);
|
1467 |
+
var offsetA = (reverse ? line.indexOf(match) + match.length : line.lastIndexOf(match));
|
1468 |
+
if (reverse ? offsetA >= pos.ch || offsetA != match.length
|
1469 |
+
: offsetA <= pos.ch || offsetA != line.length - match.length)
|
1470 |
+
return;
|
1471 |
+
for (;;) {
|
1472 |
+
if (reverse ? !ln : ln == lines.length - 1) return;
|
1473 |
+
line = fold(lines[ln += reverse ? -1 : 1].text);
|
1474 |
+
match = target[reverse ? --idx : ++idx];
|
1475 |
+
if (idx > 0 && idx < target.length - 1) {
|
1476 |
+
if (line != match) return;
|
1477 |
+
else continue;
|
1478 |
+
}
|
1479 |
+
var offsetB = (reverse ? line.lastIndexOf(match) : line.indexOf(match) + match.length);
|
1480 |
+
if (reverse ? offsetB != line.length - match.length : offsetB != match.length)
|
1481 |
+
return;
|
1482 |
+
var start = {line: pos.line, ch: offsetA}, end = {line: ln, ch: offsetB};
|
1483 |
+
return {from: reverse ? end : start, to: reverse ? start : end};
|
1484 |
+
}
|
1485 |
+
};
|
1486 |
+
}
|
1487 |
+
}
|
1488 |
+
|
1489 |
+
SearchCursor.prototype = {
|
1490 |
+
findNext: function() {return this.find(false);},
|
1491 |
+
findPrevious: function() {return this.find(true);},
|
1492 |
+
|
1493 |
+
find: function(reverse) {
|
1494 |
+
var self = this, pos = clipPos(reverse ? this.pos.from : this.pos.to);
|
1495 |
+
function savePosAndFail(line) {
|
1496 |
+
var pos = {line: line, ch: 0};
|
1497 |
+
self.pos = {from: pos, to: pos};
|
1498 |
+
self.atOccurrence = false;
|
1499 |
+
return false;
|
1500 |
+
}
|
1501 |
+
|
1502 |
+
for (;;) {
|
1503 |
+
if (this.pos = this.matches(reverse, pos)) {
|
1504 |
+
this.atOccurrence = true;
|
1505 |
+
return this.pos.match || true;
|
1506 |
+
}
|
1507 |
+
if (reverse) {
|
1508 |
+
if (!pos.line) return savePosAndFail(0);
|
1509 |
+
pos = {line: pos.line-1, ch: lines[pos.line-1].text.length};
|
1510 |
+
}
|
1511 |
+
else {
|
1512 |
+
if (pos.line == lines.length - 1) return savePosAndFail(lines.length);
|
1513 |
+
pos = {line: pos.line+1, ch: 0};
|
1514 |
+
}
|
1515 |
+
}
|
1516 |
+
},
|
1517 |
+
|
1518 |
+
from: function() {if (this.atOccurrence) return copyPos(this.pos.from);},
|
1519 |
+
to: function() {if (this.atOccurrence) return copyPos(this.pos.to);},
|
1520 |
+
|
1521 |
+
replace: function(newText) {
|
1522 |
+
var self = this;
|
1523 |
+
if (this.atOccurrence)
|
1524 |
+
operation(function() {
|
1525 |
+
self.pos.to = replaceRange(newText, self.pos.from, self.pos.to);
|
1526 |
+
})();
|
1527 |
+
}
|
1528 |
+
};
|
1529 |
+
|
1530 |
+
for (var ext in extensions)
|
1531 |
+
if (extensions.propertyIsEnumerable(ext) &&
|
1532 |
+
!instance.propertyIsEnumerable(ext))
|
1533 |
+
instance[ext] = extensions[ext];
|
1534 |
+
return instance;
|
1535 |
+
} // (end of function CodeMirror)
|
1536 |
+
|
1537 |
+
// The default configuration options.
|
1538 |
+
CodeMirror.defaults = {
|
1539 |
+
value: "",
|
1540 |
+
mode: null,
|
1541 |
+
theme: "default",
|
1542 |
+
indentUnit: 2,
|
1543 |
+
indentWithTabs: false,
|
1544 |
+
tabMode: "classic",
|
1545 |
+
enterMode: "indent",
|
1546 |
+
electricChars: true,
|
1547 |
+
onKeyEvent: null,
|
1548 |
+
lineNumbers: false,
|
1549 |
+
gutter: false,
|
1550 |
+
firstLineNumber: 1,
|
1551 |
+
readOnly: false,
|
1552 |
+
smartHome: true,
|
1553 |
+
onChange: null,
|
1554 |
+
onCursorActivity: null,
|
1555 |
+
onGutterClick: null,
|
1556 |
+
onHighlightComplete: null,
|
1557 |
+
onFocus: null, onBlur: null, onScroll: null,
|
1558 |
+
matchBrackets: false,
|
1559 |
+
workTime: 100,
|
1560 |
+
workDelay: 200,
|
1561 |
+
undoDepth: 40,
|
1562 |
+
tabindex: null,
|
1563 |
+
document: window.document
|
1564 |
+
};
|
1565 |
+
|
1566 |
+
// Known modes, by name and by MIME
|
1567 |
+
var modes = {}, mimeModes = {};
|
1568 |
+
CodeMirror.defineMode = function(name, mode) {
|
1569 |
+
if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
|
1570 |
+
modes[name] = mode;
|
1571 |
+
};
|
1572 |
+
CodeMirror.defineMIME = function(mime, spec) {
|
1573 |
+
mimeModes[mime] = spec;
|
1574 |
+
};
|
1575 |
+
CodeMirror.getMode = function(options, spec) {
|
1576 |
+
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec))
|
1577 |
+
spec = mimeModes[spec];
|
1578 |
+
if (typeof spec == "string")
|
1579 |
+
var mname = spec, config = {};
|
1580 |
+
else if (spec != null)
|
1581 |
+
var mname = spec.name, config = spec;
|
1582 |
+
var mfactory = modes[mname];
|
1583 |
+
if (!mfactory) {
|
1584 |
+
if (window.console) console.warn("No mode " + mname + " found, falling back to plain text.");
|
1585 |
+
return CodeMirror.getMode(options, "text/plain");
|
1586 |
+
}
|
1587 |
+
return mfactory(options, config || {});
|
1588 |
+
};
|
1589 |
+
CodeMirror.listModes = function() {
|
1590 |
+
var list = [];
|
1591 |
+
for (var m in modes)
|
1592 |
+
if (modes.propertyIsEnumerable(m)) list.push(m);
|
1593 |
+
return list;
|
1594 |
+
};
|
1595 |
+
CodeMirror.listMIMEs = function() {
|
1596 |
+
var list = [];
|
1597 |
+
for (var m in mimeModes)
|
1598 |
+
if (mimeModes.propertyIsEnumerable(m)) list.push(m);
|
1599 |
+
return list;
|
1600 |
+
};
|
1601 |
+
|
1602 |
+
var extensions = {};
|
1603 |
+
CodeMirror.defineExtension = function(name, func) {
|
1604 |
+
extensions[name] = func;
|
1605 |
+
};
|
1606 |
+
|
1607 |
+
CodeMirror.fromTextArea = function(textarea, options) {
|
1608 |
+
if (!options) options = {};
|
1609 |
+
options.value = textarea.value;
|
1610 |
+
if (!options.tabindex && textarea.tabindex)
|
1611 |
+
options.tabindex = textarea.tabindex;
|
1612 |
+
|
1613 |
+
function save() {textarea.value = instance.getValue();}
|
1614 |
+
if (textarea.form) {
|
1615 |
+
// Deplorable hack to make the submit method do the right thing.
|
1616 |
+
var rmSubmit = connect(textarea.form, "submit", save, true);
|
1617 |
+
if (typeof textarea.form.submit == "function") {
|
1618 |
+
var realSubmit = textarea.form.submit;
|
1619 |
+
function wrappedSubmit() {
|
1620 |
+
save();
|
1621 |
+
textarea.form.submit = realSubmit;
|
1622 |
+
textarea.form.submit();
|
1623 |
+
textarea.form.submit = wrappedSubmit;
|
1624 |
+
}
|
1625 |
+
textarea.form.submit = wrappedSubmit;
|
1626 |
+
}
|
1627 |
+
}
|
1628 |
+
|
1629 |
+
textarea.style.display = "none";
|
1630 |
+
var instance = CodeMirror(function(node) {
|
1631 |
+
textarea.parentNode.insertBefore(node, textarea.nextSibling);
|
1632 |
+
}, options);
|
1633 |
+
instance.save = save;
|
1634 |
+
instance.toTextArea = function() {
|
1635 |
+
save();
|
1636 |
+
textarea.parentNode.removeChild(instance.getWrapperElement());
|
1637 |
+
textarea.style.display = "";
|
1638 |
+
if (textarea.form) {
|
1639 |
+
rmSubmit();
|
1640 |
+
if (typeof textarea.form.submit == "function")
|
1641 |
+
textarea.form.submit = realSubmit;
|
1642 |
+
}
|
1643 |
+
};
|
1644 |
+
return instance;
|
1645 |
+
};
|
1646 |
+
|
1647 |
+
// Utility functions for working with state. Exported because modes
|
1648 |
+
// sometimes need to do this.
|
1649 |
+
function copyState(mode, state) {
|
1650 |
+
if (state === true) return state;
|
1651 |
+
if (mode.copyState) return mode.copyState(state);
|
1652 |
+
var nstate = {};
|
1653 |
+
for (var n in state) {
|
1654 |
+
var val = state[n];
|
1655 |
+
if (val instanceof Array) val = val.concat([]);
|
1656 |
+
nstate[n] = val;
|
1657 |
+
}
|
1658 |
+
return nstate;
|
1659 |
+
}
|
1660 |
+
CodeMirror.startState = startState;
|
1661 |
+
function startState(mode, a1, a2) {
|
1662 |
+
return mode.startState ? mode.startState(a1, a2) : true;
|
1663 |
+
}
|
1664 |
+
CodeMirror.copyState = copyState;
|
1665 |
+
|
1666 |
+
// The character stream used by a mode's parser.
|
1667 |
+
function StringStream(string) {
|
1668 |
+
this.pos = this.start = 0;
|
1669 |
+
this.string = string;
|
1670 |
+
}
|
1671 |
+
StringStream.prototype = {
|
1672 |
+
eol: function() {return this.pos >= this.string.length;},
|
1673 |
+
sol: function() {return this.pos == 0;},
|
1674 |
+
peek: function() {return this.string.charAt(this.pos);},
|
1675 |
+
next: function() {
|
1676 |
+
if (this.pos < this.string.length)
|
1677 |
+
return this.string.charAt(this.pos++);
|
1678 |
+
},
|
1679 |
+
eat: function(match) {
|
1680 |
+
var ch = this.string.charAt(this.pos);
|
1681 |
+
if (typeof match == "string") var ok = ch == match;
|
1682 |
+
else var ok = ch && (match.test ? match.test(ch) : match(ch));
|
1683 |
+
if (ok) {++this.pos; return ch;}
|
1684 |
+
},
|
1685 |
+
eatWhile: function(match) {
|
1686 |
+
var start = this.pos;
|
1687 |
+
while (this.eat(match)){}
|
1688 |
+
return this.pos > start;
|
1689 |
+
},
|
1690 |
+
eatSpace: function() {
|
1691 |
+
var start = this.pos;
|
1692 |
+
while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
|
1693 |
+
return this.pos > start;
|
1694 |
+
},
|
1695 |
+
skipToEnd: function() {this.pos = this.string.length;},
|
1696 |
+
skipTo: function(ch) {
|
1697 |
+
var found = this.string.indexOf(ch, this.pos);
|
1698 |
+
if (found > -1) {this.pos = found; return true;}
|
1699 |
+
},
|
1700 |
+
backUp: function(n) {this.pos -= n;},
|
1701 |
+
column: function() {return countColumn(this.string, this.start);},
|
1702 |
+
indentation: function() {return countColumn(this.string);},
|
1703 |
+
match: function(pattern, consume, caseInsensitive) {
|
1704 |
+
if (typeof pattern == "string") {
|
1705 |
+
function cased(str) {return caseInsensitive ? str.toLowerCase() : str;}
|
1706 |
+
if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
|
1707 |
+
if (consume !== false) this.pos += pattern.length;
|
1708 |
+
return true;
|
1709 |
+
}
|
1710 |
+
}
|
1711 |
+
else {
|
1712 |
+
var match = this.string.slice(this.pos).match(pattern);
|
1713 |
+
if (match && consume !== false) this.pos += match[0].length;
|
1714 |
+
return match;
|
1715 |
+
}
|
1716 |
+
},
|
1717 |
+
current: function(){return this.string.slice(this.start, this.pos);}
|
1718 |
+
};
|
1719 |
+
CodeMirror.StringStream = StringStream;
|
1720 |
+
|
1721 |
+
// Line objects. These hold state related to a line, including
|
1722 |
+
// highlighting info (the styles array).
|
1723 |
+
function Line(text, styles) {
|
1724 |
+
this.styles = styles || [text, null];
|
1725 |
+
this.stateAfter = null;
|
1726 |
+
this.text = text;
|
1727 |
+
this.marked = this.gutterMarker = this.className = null;
|
1728 |
+
}
|
1729 |
+
Line.prototype = {
|
1730 |
+
// Replace a piece of a line, keeping the styles around it intact.
|
1731 |
+
replace: function(from, to, text) {
|
1732 |
+
var st = [], mk = this.marked;
|
1733 |
+
copyStyles(0, from, this.styles, st);
|
1734 |
+
if (text) st.push(text, null);
|
1735 |
+
copyStyles(to, this.text.length, this.styles, st);
|
1736 |
+
this.styles = st;
|
1737 |
+
this.text = this.text.slice(0, from) + text + this.text.slice(to);
|
1738 |
+
this.stateAfter = null;
|
1739 |
+
if (mk) {
|
1740 |
+
var diff = text.length - (to - from), end = this.text.length;
|
1741 |
+
function fix(n) {return n <= Math.min(to, to + diff) ? n : n + diff;}
|
1742 |
+
for (var i = 0; i < mk.length; ++i) {
|
1743 |
+
var mark = mk[i], del = false;
|
1744 |
+
if (mark.from >= end) del = true;
|
1745 |
+
else {mark.from = fix(mark.from); if (mark.to != null) mark.to = fix(mark.to);}
|
1746 |
+
if (del || mark.from >= mark.to) {mk.splice(i, 1); i--;}
|
1747 |
+
}
|
1748 |
+
}
|
1749 |
+
},
|
1750 |
+
// Split a line in two, again keeping styles intact.
|
1751 |
+
split: function(pos, textBefore) {
|
1752 |
+
var st = [textBefore, null];
|
1753 |
+
copyStyles(pos, this.text.length, this.styles, st);
|
1754 |
+
return new Line(textBefore + this.text.slice(pos), st);
|
1755 |
+
},
|
1756 |
+
addMark: function(from, to, style) {
|
1757 |
+
var mk = this.marked, mark = {from: from, to: to, style: style};
|
1758 |
+
if (this.marked == null) this.marked = [];
|
1759 |
+
this.marked.push(mark);
|
1760 |
+
this.marked.sort(function(a, b){return a.from - b.from;});
|
1761 |
+
return mark;
|
1762 |
+
},
|
1763 |
+
removeMark: function(mark) {
|
1764 |
+
var mk = this.marked;
|
1765 |
+
if (!mk) return;
|
1766 |
+
for (var i = 0; i < mk.length; ++i)
|
1767 |
+
if (mk[i] == mark) {mk.splice(i, 1); break;}
|
1768 |
+
},
|
1769 |
+
// Run the given mode's parser over a line, update the styles
|
1770 |
+
// array, which contains alternating fragments of text and CSS
|
1771 |
+
// classes.
|
1772 |
+
highlight: function(mode, state) {
|
1773 |
+
var stream = new StringStream(this.text), st = this.styles, pos = 0;
|
1774 |
+
var changed = false, curWord = st[0], prevWord;
|
1775 |
+
if (this.text == "" && mode.blankLine) mode.blankLine(state);
|
1776 |
+
while (!stream.eol()) {
|
1777 |
+
var style = mode.token(stream, state);
|
1778 |
+
var substr = this.text.slice(stream.start, stream.pos);
|
1779 |
+
stream.start = stream.pos;
|
1780 |
+
if (pos && st[pos-1] == style)
|
1781 |
+
st[pos-2] += substr;
|
1782 |
+
else if (substr) {
|
1783 |
+
if (!changed && (st[pos+1] != style || (pos && st[pos-2] != prevWord))) changed = true;
|
1784 |
+
st[pos++] = substr; st[pos++] = style;
|
1785 |
+
prevWord = curWord; curWord = st[pos];
|
1786 |
+
}
|
1787 |
+
// Give up when line is ridiculously long
|
1788 |
+
if (stream.pos > 5000) {
|
1789 |
+
st[pos++] = this.text.slice(stream.pos); st[pos++] = null;
|
1790 |
+
break;
|
1791 |
+
}
|
1792 |
+
}
|
1793 |
+
if (st.length != pos) {st.length = pos; changed = true;}
|
1794 |
+
if (pos && st[pos-2] != prevWord) changed = true;
|
1795 |
+
// Short lines with simple highlights return null, and are
|
1796 |
+
// counted as changed by the driver because they are likely to
|
1797 |
+
// highlight the same way in various contexts.
|
1798 |
+
return changed || (st.length < 5 && this.text.length < 10 ? null : false);
|
1799 |
+
},
|
1800 |
+
// Fetch the parser token for a given character. Useful for hacks
|
1801 |
+
// that want to inspect the mode state (say, for completion).
|
1802 |
+
getTokenAt: function(mode, state, ch) {
|
1803 |
+
var txt = this.text, stream = new StringStream(txt);
|
1804 |
+
while (stream.pos < ch && !stream.eol()) {
|
1805 |
+
stream.start = stream.pos;
|
1806 |
+
var style = mode.token(stream, state);
|
1807 |
+
}
|
1808 |
+
return {start: stream.start,
|
1809 |
+
end: stream.pos,
|
1810 |
+
string: stream.current(),
|
1811 |
+
className: style || null,
|
1812 |
+
state: state};
|
1813 |
+
},
|
1814 |
+
indentation: function() {return countColumn(this.text);},
|
1815 |
+
// Produces an HTML fragment for the line, taking selection,
|
1816 |
+
// marking, and highlighting into account.
|
1817 |
+
getHTML: function(sfrom, sto, includePre, endAt) {
|
1818 |
+
var html = [];
|
1819 |
+
if (includePre)
|
1820 |
+
html.push(this.className ? '<pre class="' + this.className + '">': "<pre>");
|
1821 |
+
function span(text, style) {
|
1822 |
+
if (!text) return;
|
1823 |
+
if (style) html.push('<span class="', style, '">', htmlEscape(text), "</span>");
|
1824 |
+
else html.push(htmlEscape(text));
|
1825 |
+
}
|
1826 |
+
var st = this.styles, allText = this.text, marked = this.marked;
|
1827 |
+
if (sfrom == sto) sfrom = null;
|
1828 |
+
var len = allText.length;
|
1829 |
+
if (endAt != null) len = Math.min(endAt, len);
|
1830 |
+
|
1831 |
+
if (!allText && endAt == null)
|
1832 |
+
span(" ", sfrom != null && sto == null ? "CodeMirror-selected" : null);
|
1833 |
+
else if (!marked && sfrom == null)
|
1834 |
+
for (var i = 0, ch = 0; ch < len; i+=2) {
|
1835 |
+
var str = st[i], l = str.length;
|
1836 |
+
if (ch + l > len) str = str.slice(0, len - ch);
|
1837 |
+
ch += l;
|
1838 |
+
span(str, "cm-" + st[i+1]);
|
1839 |
+
}
|
1840 |
+
else {
|
1841 |
+
var pos = 0, i = 0, text = "", style, sg = 0;
|
1842 |
+
var markpos = -1, mark = null;
|
1843 |
+
function nextMark() {
|
1844 |
+
if (marked) {
|
1845 |
+
markpos += 1;
|
1846 |
+
mark = (markpos < marked.length) ? marked[markpos] : null;
|
1847 |
+
}
|
1848 |
+
}
|
1849 |
+
nextMark();
|
1850 |
+
while (pos < len) {
|
1851 |
+
var upto = len;
|
1852 |
+
var extraStyle = "";
|
1853 |
+
if (sfrom != null) {
|
1854 |
+
if (sfrom > pos) upto = sfrom;
|
1855 |
+
else if (sto == null || sto > pos) {
|
1856 |
+
extraStyle = " CodeMirror-selected";
|
1857 |
+
if (sto != null) upto = Math.min(upto, sto);
|
1858 |
+
}
|
1859 |
+
}
|
1860 |
+
while (mark && mark.to != null && mark.to <= pos) nextMark();
|
1861 |
+
if (mark) {
|
1862 |
+
if (mark.from > pos) upto = Math.min(upto, mark.from);
|
1863 |
+
else {
|
1864 |
+
extraStyle += " " + mark.style;
|
1865 |
+
if (mark.to != null) upto = Math.min(upto, mark.to);
|
1866 |
+
}
|
1867 |
+
}
|
1868 |
+
for (;;) {
|
1869 |
+
var end = pos + text.length;
|
1870 |
+
var appliedStyle = style;
|
1871 |
+
if (extraStyle) appliedStyle = style ? style + extraStyle : extraStyle;
|
1872 |
+
span(end > upto ? text.slice(0, upto - pos) : text, appliedStyle);
|
1873 |
+
if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
|
1874 |
+
pos = end;
|
1875 |
+
text = st[i++]; style = "cm-" + st[i++];
|
1876 |
+
}
|
1877 |
+
}
|
1878 |
+
if (sfrom != null && sto == null) span(" ", "CodeMirror-selected");
|
1879 |
+
}
|
1880 |
+
if (includePre) html.push("</pre>");
|
1881 |
+
return html.join("");
|
1882 |
+
}
|
1883 |
+
};
|
1884 |
+
// Utility used by replace and split above
|
1885 |
+
function copyStyles(from, to, source, dest) {
|
1886 |
+
for (var i = 0, pos = 0, state = 0; pos < to; i+=2) {
|
1887 |
+
var part = source[i], end = pos + part.length;
|
1888 |
+
if (state == 0) {
|
1889 |
+
if (end > from) dest.push(part.slice(from - pos, Math.min(part.length, to - pos)), source[i+1]);
|
1890 |
+
if (end >= from) state = 1;
|
1891 |
+
}
|
1892 |
+
else if (state == 1) {
|
1893 |
+
if (end > to) dest.push(part.slice(0, to - pos), source[i+1]);
|
1894 |
+
else dest.push(part, source[i+1]);
|
1895 |
+
}
|
1896 |
+
pos = end;
|
1897 |
+
}
|
1898 |
+
}
|
1899 |
+
|
1900 |
+
// The history object 'chunks' changes that are made close together
|
1901 |
+
// and at almost the same time into bigger undoable units.
|
1902 |
+
function History() {
|
1903 |
+
this.time = 0;
|
1904 |
+
this.done = []; this.undone = [];
|
1905 |
+
}
|
1906 |
+
History.prototype = {
|
1907 |
+
addChange: function(start, added, old) {
|
1908 |
+
this.undone.length = 0;
|
1909 |
+
var time = +new Date, last = this.done[this.done.length - 1];
|
1910 |
+
if (time - this.time > 400 || !last ||
|
1911 |
+
last.start > start + added || last.start + last.added < start - last.added + last.old.length)
|
1912 |
+
this.done.push({start: start, added: added, old: old});
|
1913 |
+
else {
|
1914 |
+
var oldoff = 0;
|
1915 |
+
if (start < last.start) {
|
1916 |
+
for (var i = last.start - start - 1; i >= 0; --i)
|
1917 |
+
last.old.unshift(old[i]);
|
1918 |
+
last.added += last.start - start;
|
1919 |
+
last.start = start;
|
1920 |
+
}
|
1921 |
+
else if (last.start < start) {
|
1922 |
+
oldoff = start - last.start;
|
1923 |
+
added += oldoff;
|
1924 |
+
}
|
1925 |
+
for (var i = last.added - oldoff, e = old.length; i < e; ++i)
|
1926 |
+
last.old.push(old[i]);
|
1927 |
+
if (last.added < added) last.added = added;
|
1928 |
+
}
|
1929 |
+
this.time = time;
|
1930 |
+
}
|
1931 |
+
};
|
1932 |
+
|
1933 |
+
function stopMethod() {e_stop(this);}
|
1934 |
+
// Ensure an event has a stop method.
|
1935 |
+
function addStop(event) {
|
1936 |
+
if (!event.stop) event.stop = stopMethod;
|
1937 |
+
return event;
|
1938 |
+
}
|
1939 |
+
|
1940 |
+
function e_preventDefault(e) {
|
1941 |
+
if (e.preventDefault) e.preventDefault();
|
1942 |
+
else e.returnValue = false;
|
1943 |
+
}
|
1944 |
+
function e_stopPropagation(e) {
|
1945 |
+
if (e.stopPropagation) e.stopPropagation();
|
1946 |
+
else e.cancelBubble = true;
|
1947 |
+
}
|
1948 |
+
function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
|
1949 |
+
function e_target(e) {return e.target || e.srcElement;}
|
1950 |
+
function e_button(e) {
|
1951 |
+
if (e.which) return e.which;
|
1952 |
+
else if (e.button & 1) return 1;
|
1953 |
+
else if (e.button & 2) return 3;
|
1954 |
+
else if (e.button & 4) return 2;
|
1955 |
+
}
|
1956 |
+
|
1957 |
+
// Event handler registration. If disconnect is true, it'll return a
|
1958 |
+
// function that unregisters the handler.
|
1959 |
+
function connect(node, type, handler, disconnect) {
|
1960 |
+
function wrapHandler(event) {handler(event || window.event);}
|
1961 |
+
if (typeof node.addEventListener == "function") {
|
1962 |
+
node.addEventListener(type, wrapHandler, false);
|
1963 |
+
if (disconnect) return function() {node.removeEventListener(type, wrapHandler, false);};
|
1964 |
+
}
|
1965 |
+
else {
|
1966 |
+
node.attachEvent("on" + type, wrapHandler);
|
1967 |
+
if (disconnect) return function() {node.detachEvent("on" + type, wrapHandler);};
|
1968 |
+
}
|
1969 |
+
}
|
1970 |
+
|
1971 |
+
function Delayed() {this.id = null;}
|
1972 |
+
Delayed.prototype = {set: function(ms, f) {clearTimeout(this.id); this.id = setTimeout(f, ms);}};
|
1973 |
+
|
1974 |
+
// Some IE versions don't preserve whitespace when setting the
|
1975 |
+
// innerHTML of a PRE tag.
|
1976 |
+
var badInnerHTML = (function() {
|
1977 |
+
var pre = document.createElement("pre");
|
1978 |
+
pre.innerHTML = " "; return !pre.innerHTML;
|
1979 |
+
})();
|
1980 |
+
|
1981 |
+
var gecko = /gecko\/\d{7}/i.test(navigator.userAgent);
|
1982 |
+
var ie = /MSIE \d/.test(navigator.userAgent);
|
1983 |
+
var safari = /Apple Computer/.test(navigator.vendor);
|
1984 |
+
|
1985 |
+
var lineSep = "\n";
|
1986 |
+
// Feature-detect whether newlines in textareas are converted to \r\n
|
1987 |
+
(function () {
|
1988 |
+
var te = document.createElement("textarea");
|
1989 |
+
te.value = "foo\nbar";
|
1990 |
+
if (te.value.indexOf("\r") > -1) lineSep = "\r\n";
|
1991 |
+
}());
|
1992 |
+
|
1993 |
+
var tabSize = 8;
|
1994 |
+
var mac = /Mac/.test(navigator.platform);
|
1995 |
+
var movementKeys = {};
|
1996 |
+
for (var i = 35; i <= 40; ++i)
|
1997 |
+
movementKeys[i] = movementKeys["c" + i] = true;
|
1998 |
+
|
1999 |
+
// Counts the column offset in a string, taking tabs into account.
|
2000 |
+
// Used mostly to find indentation.
|
2001 |
+
function countColumn(string, end) {
|
2002 |
+
if (end == null) {
|
2003 |
+
end = string.search(/[^\s\u00a0]/);
|
2004 |
+
if (end == -1) end = string.length;
|
2005 |
+
}
|
2006 |
+
for (var i = 0, n = 0; i < end; ++i) {
|
2007 |
+
if (string.charAt(i) == "\t") n += tabSize - (n % tabSize);
|
2008 |
+
else ++n;
|
2009 |
+
}
|
2010 |
+
return n;
|
2011 |
+
}
|
2012 |
+
|
2013 |
+
function computedStyle(elt) {
|
2014 |
+
if (elt.currentStyle) return elt.currentStyle;
|
2015 |
+
return window.getComputedStyle(elt, null);
|
2016 |
+
}
|
2017 |
+
// Find the position of an element by following the offsetParent chain.
|
2018 |
+
// If screen==true, it returns screen (rather than page) coordinates.
|
2019 |
+
function eltOffset(node, screen) {
|
2020 |
+
var doc = node.ownerDocument.body;
|
2021 |
+
var x = 0, y = 0, skipDoc = false;
|
2022 |
+
for (var n = node; n; n = n.offsetParent) {
|
2023 |
+
x += n.offsetLeft; y += n.offsetTop;
|
2024 |
+
if (screen && computedStyle(n).position == "fixed")
|
2025 |
+
skipDoc = true;
|
2026 |
+
}
|
2027 |
+
var e = screen && !skipDoc ? null : doc;
|
2028 |
+
for (var n = node.parentNode; n != e; n = n.parentNode)
|
2029 |
+
if (n.scrollLeft != null) { x -= n.scrollLeft; y -= n.scrollTop;}
|
2030 |
+
return {left: x, top: y};
|
2031 |
+
}
|
2032 |
+
// Get a node's text content.
|
2033 |
+
function eltText(node) {
|
2034 |
+
return node.textContent || node.innerText || node.nodeValue || "";
|
2035 |
+
}
|
2036 |
+
|
2037 |
+
// Operations on {line, ch} objects.
|
2038 |
+
function posEq(a, b) {return a.line == b.line && a.ch == b.ch;}
|
2039 |
+
function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);}
|
2040 |
+
function copyPos(x) {return {line: x.line, ch: x.ch};}
|
2041 |
+
|
2042 |
+
var escapeElement = document.createElement("div");
|
2043 |
+
function htmlEscape(str) {
|
2044 |
+
escapeElement.innerText = escapeElement.textContent = str;
|
2045 |
+
return escapeElement.innerHTML;
|
2046 |
+
}
|
2047 |
+
CodeMirror.htmlEscape = htmlEscape;
|
2048 |
+
|
2049 |
+
// Used to position the cursor after an undo/redo by finding the
|
2050 |
+
// last edited character.
|
2051 |
+
function editEnd(from, to) {
|
2052 |
+
if (!to) return from ? from.length : 0;
|
2053 |
+
if (!from) return to.length;
|
2054 |
+
for (var i = from.length, j = to.length; i >= 0 && j >= 0; --i, --j)
|
2055 |
+
if (from.charAt(i) != to.charAt(j)) break;
|
2056 |
+
return j + 1;
|
2057 |
+
}
|
2058 |
+
|
2059 |
+
function indexOf(collection, elt) {
|
2060 |
+
if (collection.indexOf) return collection.indexOf(elt);
|
2061 |
+
for (var i = 0, e = collection.length; i < e; ++i)
|
2062 |
+
if (collection[i] == elt) return i;
|
2063 |
+
return -1;
|
2064 |
+
}
|
2065 |
+
|
2066 |
+
// See if "".split is the broken IE version, if so, provide an
|
2067 |
+
// alternative way to split lines.
|
2068 |
+
var splitLines, selRange, setSelRange;
|
2069 |
+
if ("\n\nb".split(/\n/).length != 3)
|
2070 |
+
splitLines = function(string) {
|
2071 |
+
var pos = 0, nl, result = [];
|
2072 |
+
while ((nl = string.indexOf("\n", pos)) > -1) {
|
2073 |
+
result.push(string.slice(pos, string.charAt(nl-1) == "\r" ? nl - 1 : nl));
|
2074 |
+
pos = nl + 1;
|
2075 |
+
}
|
2076 |
+
result.push(string.slice(pos));
|
2077 |
+
return result;
|
2078 |
+
};
|
2079 |
+
else
|
2080 |
+
splitLines = function(string){return string.split(/\r?\n/);};
|
2081 |
+
CodeMirror.splitLines = splitLines;
|
2082 |
+
|
2083 |
+
// Sane model of finding and setting the selection in a textarea
|
2084 |
+
if (window.getSelection) {
|
2085 |
+
selRange = function(te) {
|
2086 |
+
try {return {start: te.selectionStart, end: te.selectionEnd};}
|
2087 |
+
catch(e) {return null;}
|
2088 |
+
};
|
2089 |
+
if (safari)
|
2090 |
+
// On Safari, selection set with setSelectionRange are in a sort
|
2091 |
+
// of limbo wrt their anchor. If you press shift-left in them,
|
2092 |
+
// the anchor is put at the end, and the selection expanded to
|
2093 |
+
// the left. If you press shift-right, the anchor ends up at the
|
2094 |
+
// front. This is not what CodeMirror wants, so it does a
|
2095 |
+
// spurious modify() call to get out of limbo.
|
2096 |
+
setSelRange = function(te, start, end) {
|
2097 |
+
if (start == end)
|
2098 |
+
te.setSelectionRange(start, end);
|
2099 |
+
else {
|
2100 |
+
te.setSelectionRange(start, end - 1);
|
2101 |
+
window.getSelection().modify("extend", "forward", "character");
|
2102 |
+
}
|
2103 |
+
};
|
2104 |
+
else
|
2105 |
+
setSelRange = function(te, start, end) {
|
2106 |
+
try {te.setSelectionRange(start, end);}
|
2107 |
+
catch(e) {} // Fails on Firefox when textarea isn't part of the document
|
2108 |
+
};
|
2109 |
+
}
|
2110 |
+
// IE model. Don't ask.
|
2111 |
+
else {
|
2112 |
+
selRange = function(te) {
|
2113 |
+
try {var range = te.ownerDocument.selection.createRange();}
|
2114 |
+
catch(e) {return null;}
|
2115 |
+
if (!range || range.parentElement() != te) return null;
|
2116 |
+
var val = te.value, len = val.length, localRange = te.createTextRange();
|
2117 |
+
localRange.moveToBookmark(range.getBookmark());
|
2118 |
+
var endRange = te.createTextRange();
|
2119 |
+
endRange.collapse(false);
|
2120 |
+
|
2121 |
+
if (localRange.compareEndPoints("StartToEnd", endRange) > -1)
|
2122 |
+
return {start: len, end: len};
|
2123 |
+
|
2124 |
+
var start = -localRange.moveStart("character", -len);
|
2125 |
+
for (var i = val.indexOf("\r"); i > -1 && i < start; i = val.indexOf("\r", i+1), start++) {}
|
2126 |
+
|
2127 |
+
if (localRange.compareEndPoints("EndToEnd", endRange) > -1)
|
2128 |
+
return {start: start, end: len};
|
2129 |
+
|
2130 |
+
var end = -localRange.moveEnd("character", -len);
|
2131 |
+
for (var i = val.indexOf("\r"); i > -1 && i < end; i = val.indexOf("\r", i+1), end++) {}
|
2132 |
+
return {start: start, end: end};
|
2133 |
+
};
|
2134 |
+
setSelRange = function(te, start, end) {
|
2135 |
+
var range = te.createTextRange();
|
2136 |
+
range.collapse(true);
|
2137 |
+
var endrange = range.duplicate();
|
2138 |
+
var newlines = 0, txt = te.value;
|
2139 |
+
for (var pos = txt.indexOf("\n"); pos > -1 && pos < start; pos = txt.indexOf("\n", pos + 1))
|
2140 |
+
++newlines;
|
2141 |
+
range.move("character", start - newlines);
|
2142 |
+
for (; pos > -1 && pos < end; pos = txt.indexOf("\n", pos + 1))
|
2143 |
+
++newlines;
|
2144 |
+
endrange.move("character", end - newlines);
|
2145 |
+
range.setEndPoint("EndToEnd", endrange);
|
2146 |
+
range.select();
|
2147 |
+
};
|
2148 |
+
}
|
2149 |
+
|
2150 |
+
CodeMirror.defineMode("null", function() {
|
2151 |
+
return {token: function(stream) {stream.skipToEnd();}};
|
2152 |
+
});
|
2153 |
+
CodeMirror.defineMIME("text/plain", "null");
|
2154 |
+
|
2155 |
+
return CodeMirror;
|
2156 |
+
})()
|
2157 |
+
;
|
tinymce-plugins/cmseditor/js/lib/overlay.js
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Utility function that allows modes to be combined. The mode given
|
2 |
+
// as the base argument takes care of most of the normal mode
|
3 |
+
// functionality, but a second (typically simple) mode is used, which
|
4 |
+
// can override the style of text. Both modes get to parse all of the
|
5 |
+
// text, but when both assign a non-null style to a piece of code, the
|
6 |
+
// overlay wins, unless the combine argument was true, in which case
|
7 |
+
// the styles are combined.
|
8 |
+
|
9 |
+
CodeMirror.overlayParser = function(base, overlay, combine) {
|
10 |
+
return {
|
11 |
+
startState: function() {
|
12 |
+
return {
|
13 |
+
base: CodeMirror.startState(base),
|
14 |
+
overlay: CodeMirror.startState(overlay),
|
15 |
+
basePos: 0, baseCur: null,
|
16 |
+
overlayPos: 0, overlayCur: null
|
17 |
+
};
|
18 |
+
},
|
19 |
+
copyState: function(state) {
|
20 |
+
return {
|
21 |
+
base: CodeMirror.copyState(base, state.base),
|
22 |
+
overlay: CodeMirror.copyState(overlay, state.overlay),
|
23 |
+
basePos: state.basePos, baseCur: null,
|
24 |
+
overlayPos: state.overlayPos, overlayCur: null
|
25 |
+
};
|
26 |
+
},
|
27 |
+
|
28 |
+
token: function(stream, state) {
|
29 |
+
if (stream.start == state.basePos) {
|
30 |
+
state.baseCur = base.token(stream, state.base);
|
31 |
+
state.basePos = stream.pos;
|
32 |
+
}
|
33 |
+
if (stream.start == state.overlayPos) {
|
34 |
+
stream.pos = stream.start;
|
35 |
+
state.overlayCur = overlay.token(stream, state.overlay);
|
36 |
+
state.overlayPos = stream.pos;
|
37 |
+
}
|
38 |
+
stream.pos = Math.min(state.basePos, state.overlayPos);
|
39 |
+
if (stream.eol()) state.basePos = state.overlayPos = 0;
|
40 |
+
|
41 |
+
if (state.overlayCur == null) return state.baseCur;
|
42 |
+
if (state.baseCur != null && combine) return state.baseCur + " " + state.overlayCur;
|
43 |
+
else return state.overlayCur;
|
44 |
+
},
|
45 |
+
|
46 |
+
indent: function(state, textAfter) {
|
47 |
+
return base.indent(state.base, textAfter);
|
48 |
+
},
|
49 |
+
electricChars: base.electricChars
|
50 |
+
};
|
51 |
+
};
|
tinymce-plugins/cmseditor/js/lib/runmode.js
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
CodeMirror.runMode = function(string, modespec, callback) {
|
2 |
+
var mode = CodeMirror.getMode({indentUnit: 2}, modespec);
|
3 |
+
var isNode = callback.nodeType == 1;
|
4 |
+
if (isNode) {
|
5 |
+
var node = callback, accum = [];
|
6 |
+
callback = function(string, style) {
|
7 |
+
if (string == "\n")
|
8 |
+
accum.push("<br>");
|
9 |
+
else if (style)
|
10 |
+
accum.push("<span class=\"cm-" + CodeMirror.htmlEscape(style) + "\">" + CodeMirror.htmlEscape(string) + "</span>");
|
11 |
+
else
|
12 |
+
accum.push(CodeMirror.htmlEscape(string));
|
13 |
+
}
|
14 |
+
}
|
15 |
+
var lines = CodeMirror.splitLines(string), state = CodeMirror.startState(mode);
|
16 |
+
for (var i = 0, e = lines.length; i < e; ++i) {
|
17 |
+
if (i) callback("\n");
|
18 |
+
var stream = new CodeMirror.StringStream(lines[i]);
|
19 |
+
while (!stream.eol()) {
|
20 |
+
var style = mode.token(stream, state);
|
21 |
+
callback(stream.current(), style);
|
22 |
+
stream.start = stream.pos;
|
23 |
+
}
|
24 |
+
}
|
25 |
+
if (isNode)
|
26 |
+
node.innerHTML = accum.join("");
|
27 |
+
};
|
tinymce-plugins/cmseditor/js/mode/css/css.js
ADDED
@@ -0,0 +1,124 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
CodeMirror.defineMode("css", function(config) {
|
2 |
+
var indentUnit = config.indentUnit, type;
|
3 |
+
function ret(style, tp) {type = tp; return style;}
|
4 |
+
|
5 |
+
function tokenBase(stream, state) {
|
6 |
+
var ch = stream.next();
|
7 |
+
if (ch == "@") {stream.eatWhile(/\w/); return ret("meta", stream.current());}
|
8 |
+
else if (ch == "/" && stream.eat("*")) {
|
9 |
+
state.tokenize = tokenCComment;
|
10 |
+
return tokenCComment(stream, state);
|
11 |
+
}
|
12 |
+
else if (ch == "<" && stream.eat("!")) {
|
13 |
+
state.tokenize = tokenSGMLComment;
|
14 |
+
return tokenSGMLComment(stream, state);
|
15 |
+
}
|
16 |
+
else if (ch == "=") ret(null, "compare");
|
17 |
+
else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
|
18 |
+
else if (ch == "\"" || ch == "'") {
|
19 |
+
state.tokenize = tokenString(ch);
|
20 |
+
return state.tokenize(stream, state);
|
21 |
+
}
|
22 |
+
else if (ch == "#") {
|
23 |
+
stream.eatWhile(/\w/);
|
24 |
+
return ret("atom", "hash");
|
25 |
+
}
|
26 |
+
else if (ch == "!") {
|
27 |
+
stream.match(/^\s*\w*/);
|
28 |
+
return ret("keyword", "important");
|
29 |
+
}
|
30 |
+
else if (/\d/.test(ch)) {
|
31 |
+
stream.eatWhile(/[\w.%]/);
|
32 |
+
return ret("number", "unit");
|
33 |
+
}
|
34 |
+
else if (/[,.+>*\/]/.test(ch)) {
|
35 |
+
return ret(null, "select-op");
|
36 |
+
}
|
37 |
+
else if (/[;{}:\[\]]/.test(ch)) {
|
38 |
+
return ret(null, ch);
|
39 |
+
}
|
40 |
+
else {
|
41 |
+
stream.eatWhile(/[\w\\\-_]/);
|
42 |
+
return ret("variable", "variable");
|
43 |
+
}
|
44 |
+
}
|
45 |
+
|
46 |
+
function tokenCComment(stream, state) {
|
47 |
+
var maybeEnd = false, ch;
|
48 |
+
while ((ch = stream.next()) != null) {
|
49 |
+
if (maybeEnd && ch == "/") {
|
50 |
+
state.tokenize = tokenBase;
|
51 |
+
break;
|
52 |
+
}
|
53 |
+
maybeEnd = (ch == "*");
|
54 |
+
}
|
55 |
+
return ret("comment", "comment");
|
56 |
+
}
|
57 |
+
|
58 |
+
function tokenSGMLComment(stream, state) {
|
59 |
+
var dashes = 0, ch;
|
60 |
+
while ((ch = stream.next()) != null) {
|
61 |
+
if (dashes >= 2 && ch == ">") {
|
62 |
+
state.tokenize = tokenBase;
|
63 |
+
break;
|
64 |
+
}
|
65 |
+
dashes = (ch == "-") ? dashes + 1 : 0;
|
66 |
+
}
|
67 |
+
return ret("comment", "comment");
|
68 |
+
}
|
69 |
+
|
70 |
+
function tokenString(quote) {
|
71 |
+
return function(stream, state) {
|
72 |
+
var escaped = false, ch;
|
73 |
+
while ((ch = stream.next()) != null) {
|
74 |
+
if (ch == quote && !escaped)
|
75 |
+
break;
|
76 |
+
escaped = !escaped && ch == "\\";
|
77 |
+
}
|
78 |
+
if (!escaped) state.tokenize = tokenBase;
|
79 |
+
return ret("string", "string");
|
80 |
+
};
|
81 |
+
}
|
82 |
+
|
83 |
+
return {
|
84 |
+
startState: function(base) {
|
85 |
+
return {tokenize: tokenBase,
|
86 |
+
baseIndent: base || 0,
|
87 |
+
stack: []};
|
88 |
+
},
|
89 |
+
|
90 |
+
token: function(stream, state) {
|
91 |
+
if (stream.eatSpace()) return null;
|
92 |
+
var style = state.tokenize(stream, state);
|
93 |
+
|
94 |
+
var context = state.stack[state.stack.length-1];
|
95 |
+
if (type == "hash" && context == "rule") style = "atom";
|
96 |
+
else if (style == "variable") {
|
97 |
+
if (context == "rule") style = "number";
|
98 |
+
else if (!context || context == "@media{") style = "tag";
|
99 |
+
}
|
100 |
+
|
101 |
+
if (context == "rule" && /^[\{\};]$/.test(type))
|
102 |
+
state.stack.pop();
|
103 |
+
if (type == "{") {
|
104 |
+
if (context == "@media") state.stack[state.stack.length-1] = "@media{";
|
105 |
+
else state.stack.push("{");
|
106 |
+
}
|
107 |
+
else if (type == "}") state.stack.pop();
|
108 |
+
else if (type == "@media") state.stack.push("@media");
|
109 |
+
else if (context == "{" && type != "comment") state.stack.push("rule");
|
110 |
+
return style;
|
111 |
+
},
|
112 |
+
|
113 |
+
indent: function(state, textAfter) {
|
114 |
+
var n = state.stack.length;
|
115 |
+
if (/^\}/.test(textAfter))
|
116 |
+
n -= state.stack[state.stack.length-1] == "rule" ? 2 : 1;
|
117 |
+
return state.baseIndent + n * indentUnit;
|
118 |
+
},
|
119 |
+
|
120 |
+
electricChars: "}"
|
121 |
+
};
|
122 |
+
});
|
123 |
+
|
124 |
+
CodeMirror.defineMIME("text/css", "css");
|
tinymce-plugins/cmseditor/js/mode/css/index.html
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!doctype html>
|
2 |
+
<html>
|
3 |
+
<head>
|
4 |
+
<title>CodeMirror 2: CSS mode</title>
|
5 |
+
<link rel="stylesheet" href="../../lib/codemirror.css">
|
6 |
+
<script src="../../lib/codemirror.js"></script>
|
7 |
+
<script src="css.js"></script>
|
8 |
+
<link rel="stylesheet" href="../../theme/default.css">
|
9 |
+
<style>.CodeMirror {background: #f8f8f8;}</style>
|
10 |
+
<link rel="stylesheet" href="../../css/docs.css">
|
11 |
+
</head>
|
12 |
+
<body>
|
13 |
+
<h1>CodeMirror 2: CSS mode</h1>
|
14 |
+
<form><textarea id="code" name="code">
|
15 |
+
/* Some example CSS */
|
16 |
+
|
17 |
+
@import url("something.css");
|
18 |
+
|
19 |
+
body {
|
20 |
+
margin: 0;
|
21 |
+
padding: 3em 6em;
|
22 |
+
font-family: tahoma, arial, sans-serif;
|
23 |
+
color: #000;
|
24 |
+
}
|
25 |
+
|
26 |
+
#navigation a {
|
27 |
+
font-weight: bold;
|
28 |
+
text-decoration: none !important;
|
29 |
+
}
|
30 |
+
|
31 |
+
h1 {
|
32 |
+
font-size: 2.5em;
|
33 |
+
}
|
34 |
+
|
35 |
+
h2 {
|
36 |
+
font-size: 1.7em;
|
37 |
+
}
|
38 |
+
|
39 |
+
h1:before, h2:before {
|
40 |
+
content: "::";
|
41 |
+
}
|
42 |
+
|
43 |
+
code {
|
44 |
+
font-family: courier, monospace;
|
45 |
+
font-size: 80%;
|
46 |
+
color: #418A8A;
|
47 |
+
}
|
48 |
+
</textarea></form>
|
49 |
+
<script>
|
50 |
+
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
|
51 |
+
</script>
|
52 |
+
|
53 |
+
<p><strong>MIME types defined:</strong> <code>text/css</code>.</p>
|
54 |
+
|
55 |
+
</body>
|
56 |
+
</html>
|
tinymce-plugins/cmseditor/js/mode/htmlmixed/htmlmixed.js
ADDED
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
|
2 |
+
var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true});
|
3 |
+
var jsMode = CodeMirror.getMode(config, "javascript");
|
4 |
+
var cssMode = CodeMirror.getMode(config, "css");
|
5 |
+
|
6 |
+
function html(stream, state) {
|
7 |
+
var style = htmlMode.token(stream, state.htmlState);
|
8 |
+
if (style == "tag" && stream.current() == ">" && state.htmlState.context) {
|
9 |
+
if (/^script$/i.test(state.htmlState.context.tagName)) {
|
10 |
+
state.token = javascript;
|
11 |
+
state.localState = jsMode.startState(htmlMode.indent(state.htmlState, ""));
|
12 |
+
state.mode = "javascript";
|
13 |
+
}
|
14 |
+
else if (/^style$/i.test(state.htmlState.context.tagName)) {
|
15 |
+
state.token = css;
|
16 |
+
state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
|
17 |
+
state.mode = "css";
|
18 |
+
}
|
19 |
+
}
|
20 |
+
return style;
|
21 |
+
}
|
22 |
+
function maybeBackup(stream, pat, style) {
|
23 |
+
var cur = stream.current();
|
24 |
+
var close = cur.search(pat);
|
25 |
+
if (close > -1) stream.backUp(cur.length - close);
|
26 |
+
return style;
|
27 |
+
}
|
28 |
+
function javascript(stream, state) {
|
29 |
+
if (stream.match(/^<\/\s*script\s*>/i, false)) {
|
30 |
+
state.token = html;
|
31 |
+
state.curState = null;
|
32 |
+
state.mode = "html";
|
33 |
+
return html(stream, state);
|
34 |
+
}
|
35 |
+
return maybeBackup(stream, /<\/\s*script\s*>/,
|
36 |
+
jsMode.token(stream, state.localState));
|
37 |
+
}
|
38 |
+
function css(stream, state) {
|
39 |
+
if (stream.match(/^<\/\s*style\s*>/i, false)) {
|
40 |
+
state.token = html;
|
41 |
+
state.localState = null;
|
42 |
+
state.mode = "html";
|
43 |
+
return html(stream, state);
|
44 |
+
}
|
45 |
+
return maybeBackup(stream, /<\/\s*style\s*>/,
|
46 |
+
cssMode.token(stream, state.localState));
|
47 |
+
}
|
48 |
+
|
49 |
+
return {
|
50 |
+
startState: function() {
|
51 |
+
var state = htmlMode.startState();
|
52 |
+
return {token: html, localState: null, mode: "html", htmlState: state};
|
53 |
+
},
|
54 |
+
|
55 |
+
copyState: function(state) {
|
56 |
+
if (state.localState)
|
57 |
+
var local = CodeMirror.copyState(state.token == css ? cssMode : jsMode, state.localState);
|
58 |
+
return {token: state.token, localState: local, mode: state.mode,
|
59 |
+
htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
|
60 |
+
},
|
61 |
+
|
62 |
+
token: function(stream, state) {
|
63 |
+
return state.token(stream, state);
|
64 |
+
},
|
65 |
+
|
66 |
+
indent: function(state, textAfter) {
|
67 |
+
if (state.token == html || /^\s*<\//.test(textAfter))
|
68 |
+
return htmlMode.indent(state.htmlState, textAfter);
|
69 |
+
else if (state.token == javascript)
|
70 |
+
return jsMode.indent(state.localState, textAfter);
|
71 |
+
else
|
72 |
+
return cssMode.indent(state.localState, textAfter);
|
73 |
+
},
|
74 |
+
|
75 |
+
electricChars: "/{}:"
|
76 |
+
}
|
77 |
+
});
|
78 |
+
|
79 |
+
CodeMirror.defineMIME("text/html", "htmlmixed");
|
tinymce-plugins/cmseditor/js/mode/htmlmixed/index.html
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!doctype html>
|
2 |
+
<html>
|
3 |
+
<head>
|
4 |
+
<title>CodeMirror 2: HTML mixed mode</title>
|
5 |
+
<link rel="stylesheet" href="../../lib/codemirror.css">
|
6 |
+
<script src="../../lib/codemirror.js"></script>
|
7 |
+
<script src="../xml/xml.js"></script>
|
8 |
+
<script src="../javascript/javascript.js"></script>
|
9 |
+
<script src="../css/css.js"></script>
|
10 |
+
<link rel="stylesheet" href="../../theme/default.css">
|
11 |
+
<script src="htmlmixed.js"></script>
|
12 |
+
<link rel="stylesheet" href="../../css/docs.css">
|
13 |
+
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
14 |
+
</head>
|
15 |
+
<body>
|
16 |
+
<h1>CodeMirror 2: HTML mixed mode</h1>
|
17 |
+
<form><textarea id="code" name="code">
|
18 |
+
<html style="color: green">
|
19 |
+
<!-- this is a comment -->
|
20 |
+
<head>
|
21 |
+
<title>Mixed HTML Example</title>
|
22 |
+
<style type="text/css">
|
23 |
+
h1 {font-family: comic sans; color: #f0f;}
|
24 |
+
div {background: yellow !important;}
|
25 |
+
body {
|
26 |
+
max-width: 50em;
|
27 |
+
margin: 1em 2em 1em 5em;
|
28 |
+
}
|
29 |
+
</style>
|
30 |
+
</head>
|
31 |
+
<body>
|
32 |
+
<h1>Mixed HTML Example</h1>
|
33 |
+
<script>
|
34 |
+
function jsFunc(arg1, arg2) {
|
35 |
+
if (arg1 && arg2) document.body.innerHTML = "achoo";
|
36 |
+
}
|
37 |
+
</script>
|
38 |
+
</body>
|
39 |
+
</html>
|
40 |
+
</textarea></form>
|
41 |
+
<script>
|
42 |
+
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: "text/html", tabMode: "indent"});
|
43 |
+
</script>
|
44 |
+
|
45 |
+
<p>The HTML mixed mode depends on the XML, JavaScript, and CSS modes.</p>
|
46 |
+
|
47 |
+
<p><strong>MIME types defined:</strong> <code>text/html</code>
|
48 |
+
(redefined, only takes effect if you load this parser after the
|
49 |
+
XML parser).</p>
|
50 |
+
|
51 |
+
</body>
|
52 |
+
</html>
|
tinymce-plugins/cmseditor/js/mode/javascript/index.html
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!doctype html>
|
2 |
+
<html>
|
3 |
+
<head>
|
4 |
+
<title>CodeMirror 2: JavaScript mode</title>
|
5 |
+
<link rel="stylesheet" href="../../lib/codemirror.css">
|
6 |
+
<script src="../../lib/codemirror.js"></script>
|
7 |
+
<script src="javascript.js"></script>
|
8 |
+
<link rel="stylesheet" href="../../theme/default.css">
|
9 |
+
<link rel="stylesheet" href="../../css/docs.css">
|
10 |
+
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
11 |
+
</head>
|
12 |
+
<body>
|
13 |
+
<h1>CodeMirror 2: JavaScript mode</h1>
|
14 |
+
|
15 |
+
<div><textarea id="code" name="code">
|
16 |
+
// Demo code (the actual new parser character stream implementation)
|
17 |
+
|
18 |
+
function StringStream(string) {
|
19 |
+
this.pos = 0;
|
20 |
+
this.string = string;
|
21 |
+
}
|
22 |
+
|
23 |
+
StringStream.prototype = {
|
24 |
+
done: function() {return this.pos >= this.string.length;},
|
25 |
+
peek: function() {return this.string.charAt(this.pos);},
|
26 |
+
next: function() {
|
27 |
+
if (this.pos < this.string.length)
|
28 |
+
return this.string.charAt(this.pos++);
|
29 |
+
},
|
30 |
+
eat: function(match) {
|
31 |
+
var ch = this.string.charAt(this.pos);
|
32 |
+
if (typeof match == "string") var ok = ch == match;
|
33 |
+
else var ok = ch && match.test ? match.test(ch) : match(ch);
|
34 |
+
if (ok) {this.pos++; return ch;}
|
35 |
+
},
|
36 |
+
eatWhile: function(match) {
|
37 |
+
var start = this.pos;
|
38 |
+
while (this.eat(match));
|
39 |
+
if (this.pos > start) return this.string.slice(start, this.pos);
|
40 |
+
},
|
41 |
+
backUp: function(n) {this.pos -= n;},
|
42 |
+
column: function() {return this.pos;},
|
43 |
+
eatSpace: function() {
|
44 |
+
var start = this.pos;
|
45 |
+
while (/\s/.test(this.string.charAt(this.pos))) this.pos++;
|
46 |
+
return this.pos - start;
|
47 |
+
},
|
48 |
+
match: function(pattern, consume, caseInsensitive) {
|
49 |
+
if (typeof pattern == "string") {
|
50 |
+
function cased(str) {return caseInsensitive ? str.toLowerCase() : str;}
|
51 |
+
if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
|
52 |
+
if (consume !== false) this.pos += str.length;
|
53 |
+
return true;
|
54 |
+
}
|
55 |
+
}
|
56 |
+
else {
|
57 |
+
var match = this.string.slice(this.pos).match(pattern);
|
58 |
+
if (match && consume !== false) this.pos += match[0].length;
|
59 |
+
return match;
|
60 |
+
}
|
61 |
+
}
|
62 |
+
};
|
63 |
+
</textarea></div>
|
64 |
+
|
65 |
+
<script>
|
66 |
+
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
67 |
+
lineNumbers: true,
|
68 |
+
matchBrackets: true
|
69 |
+
});
|
70 |
+
</script>
|
71 |
+
|
72 |
+
<p>JavaScript mode supports a single configuration
|
73 |
+
option, <code>json</code>, which will set the mode to expect JSON
|
74 |
+
data rather than a JavaScript program.</p>
|
75 |
+
|
76 |
+
<p><strong>MIME types defined:</strong> <code>text/javascript</code>, <code>application/json</code>.</p>
|
77 |
+
</body>
|
78 |
+
</html>
|
tinymce-plugins/cmseditor/js/mode/javascript/javascript.js
ADDED
@@ -0,0 +1,348 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
2 |
+
var indentUnit = config.indentUnit;
|
3 |
+
var jsonMode = parserConfig.json;
|
4 |
+
|
5 |
+
// Tokenizer
|
6 |
+
|
7 |
+
var keywords = function(){
|
8 |
+
function kw(type) {return {type: type, style: "keyword"};}
|
9 |
+
var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
|
10 |
+
var operator = kw("operator"), atom = {type: "atom", style: "atom"};
|
11 |
+
return {
|
12 |
+
"if": A, "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
|
13 |
+
"return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C,
|
14 |
+
"var": kw("var"), "function": kw("function"), "catch": kw("catch"),
|
15 |
+
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
|
16 |
+
"in": operator, "typeof": operator, "instanceof": operator,
|
17 |
+
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom
|
18 |
+
};
|
19 |
+
}();
|
20 |
+
|
21 |
+
var isOperatorChar = /[+\-*&%=<>!?|]/;
|
22 |
+
|
23 |
+
function chain(stream, state, f) {
|
24 |
+
state.tokenize = f;
|
25 |
+
return f(stream, state);
|
26 |
+
}
|
27 |
+
|
28 |
+
function nextUntilUnescaped(stream, end) {
|
29 |
+
var escaped = false, next;
|
30 |
+
while ((next = stream.next()) != null) {
|
31 |
+
if (next == end && !escaped)
|
32 |
+
return false;
|
33 |
+
escaped = !escaped && next == "\\";
|
34 |
+
}
|
35 |
+
return escaped;
|
36 |
+
}
|
37 |
+
|
38 |
+
// Used as scratch variables to communicate multiple values without
|
39 |
+
// consing up tons of objects.
|
40 |
+
var type, content;
|
41 |
+
function ret(tp, style, cont) {
|
42 |
+
type = tp; content = cont;
|
43 |
+
return style;
|
44 |
+
}
|
45 |
+
|
46 |
+
function jsTokenBase(stream, state) {
|
47 |
+
var ch = stream.next();
|
48 |
+
if (ch == '"' || ch == "'")
|
49 |
+
return chain(stream, state, jsTokenString(ch));
|
50 |
+
else if (/[\[\]{}\(\),;\:\.]/.test(ch))
|
51 |
+
return ret(ch);
|
52 |
+
else if (ch == "0" && stream.eat(/x/i)) {
|
53 |
+
stream.eatWhile(/[\da-f]/i);
|
54 |
+
return ret("number", "number");
|
55 |
+
}
|
56 |
+
else if (/\d/.test(ch)) {
|
57 |
+
stream.match(/^\d*(?:\.\d*)?(?:e[+\-]?\d+)?/);
|
58 |
+
return ret("number", "number");
|
59 |
+
}
|
60 |
+
else if (ch == "/") {
|
61 |
+
if (stream.eat("*")) {
|
62 |
+
return chain(stream, state, jsTokenComment);
|
63 |
+
}
|
64 |
+
else if (stream.eat("/")) {
|
65 |
+
stream.skipToEnd();
|
66 |
+
return ret("comment", "comment");
|
67 |
+
}
|
68 |
+
else if (state.reAllowed) {
|
69 |
+
nextUntilUnescaped(stream, "/");
|
70 |
+
stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
|
71 |
+
return ret("regexp", "string");
|
72 |
+
}
|
73 |
+
else {
|
74 |
+
stream.eatWhile(isOperatorChar);
|
75 |
+
return ret("operator", null, stream.current());
|
76 |
+
}
|
77 |
+
}
|
78 |
+
else if (isOperatorChar.test(ch)) {
|
79 |
+
stream.eatWhile(isOperatorChar);
|
80 |
+
return ret("operator", null, stream.current());
|
81 |
+
}
|
82 |
+
else {
|
83 |
+
stream.eatWhile(/[\w\$_]/);
|
84 |
+
var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
|
85 |
+
return known ? ret(known.type, known.style, word) :
|
86 |
+
ret("variable", "variable", word);
|
87 |
+
}
|
88 |
+
}
|
89 |
+
|
90 |
+
function jsTokenString(quote) {
|
91 |
+
return function(stream, state) {
|
92 |
+
if (!nextUntilUnescaped(stream, quote))
|
93 |
+
state.tokenize = jsTokenBase;
|
94 |
+
return ret("string", "string");
|
95 |
+
};
|
96 |
+
}
|
97 |
+
|
98 |
+
function jsTokenComment(stream, state) {
|
99 |
+
var maybeEnd = false, ch;
|
100 |
+
while (ch = stream.next()) {
|
101 |
+
if (ch == "/" && maybeEnd) {
|
102 |
+
state.tokenize = jsTokenBase;
|
103 |
+
break;
|
104 |
+
}
|
105 |
+
maybeEnd = (ch == "*");
|
106 |
+
}
|
107 |
+
return ret("comment", "comment");
|
108 |
+
}
|
109 |
+
|
110 |
+
// Parser
|
111 |
+
|
112 |
+
var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};
|
113 |
+
|
114 |
+
function JSLexical(indented, column, type, align, prev, info) {
|
115 |
+
this.indented = indented;
|
116 |
+
this.column = column;
|
117 |
+
this.type = type;
|
118 |
+
this.prev = prev;
|
119 |
+
this.info = info;
|
120 |
+
if (align != null) this.align = align;
|
121 |
+
}
|
122 |
+
|
123 |
+
function inScope(state, varname) {
|
124 |
+
for (var v = state.localVars; v; v = v.next)
|
125 |
+
if (v.name == varname) return true;
|
126 |
+
}
|
127 |
+
|
128 |
+
function parseJS(state, style, type, content, stream) {
|
129 |
+
var cc = state.cc;
|
130 |
+
// Communicate our context to the combinators.
|
131 |
+
// (Less wasteful than consing up a hundred closures on every call.)
|
132 |
+
cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
|
133 |
+
|
134 |
+
if (!state.lexical.hasOwnProperty("align"))
|
135 |
+
state.lexical.align = true;
|
136 |
+
|
137 |
+
while(true) {
|
138 |
+
var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
|
139 |
+
if (combinator(type, content)) {
|
140 |
+
while(cc.length && cc[cc.length - 1].lex)
|
141 |
+
cc.pop()();
|
142 |
+
if (cx.marked) return cx.marked;
|
143 |
+
if (type == "variable" && inScope(state, content)) return "variable-2";
|
144 |
+
return style;
|
145 |
+
}
|
146 |
+
}
|
147 |
+
}
|
148 |
+
|
149 |
+
// Combinator utils
|
150 |
+
|
151 |
+
var cx = {state: null, column: null, marked: null, cc: null};
|
152 |
+
function pass() {
|
153 |
+
for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
|
154 |
+
}
|
155 |
+
function cont() {
|
156 |
+
pass.apply(null, arguments);
|
157 |
+
return true;
|
158 |
+
}
|
159 |
+
function register(varname) {
|
160 |
+
var state = cx.state;
|
161 |
+
if (state.context) {
|
162 |
+
cx.marked = "def";
|
163 |
+
for (var v = state.localVars; v; v = v.next)
|
164 |
+
if (v.name == varname) return;
|
165 |
+
state.localVars = {name: varname, next: state.localVars};
|
166 |
+
}
|
167 |
+
}
|
168 |
+
|
169 |
+
// Combinators
|
170 |
+
|
171 |
+
var defaultVars = {name: "this", next: {name: "arguments"}};
|
172 |
+
function pushcontext() {
|
173 |
+
if (!cx.state.context) cx.state.localVars = defaultVars;
|
174 |
+
cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
|
175 |
+
}
|
176 |
+
function popcontext() {
|
177 |
+
cx.state.localVars = cx.state.context.vars;
|
178 |
+
cx.state.context = cx.state.context.prev;
|
179 |
+
}
|
180 |
+
function pushlex(type, info) {
|
181 |
+
var result = function() {
|
182 |
+
var state = cx.state;
|
183 |
+
state.lexical = new JSLexical(state.indented, cx.stream.column(), type, null, state.lexical, info)
|
184 |
+
};
|
185 |
+
result.lex = true;
|
186 |
+
return result;
|
187 |
+
}
|
188 |
+
function poplex() {
|
189 |
+
var state = cx.state;
|
190 |
+
if (state.lexical.prev) {
|
191 |
+
if (state.lexical.type == ")")
|
192 |
+
state.indented = state.lexical.indented;
|
193 |
+
state.lexical = state.lexical.prev;
|
194 |
+
}
|
195 |
+
}
|
196 |
+
poplex.lex = true;
|
197 |
+
|
198 |
+
function expect(wanted) {
|
199 |
+
return function expecting(type) {
|
200 |
+
if (type == wanted) return cont();
|
201 |
+
else if (wanted == ";") return pass();
|
202 |
+
else return cont(arguments.callee);
|
203 |
+
};
|
204 |
+
}
|
205 |
+
|
206 |
+
function statement(type) {
|
207 |
+
if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
|
208 |
+
if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
|
209 |
+
if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
|
210 |
+
if (type == "{") return cont(pushlex("}"), block, poplex);
|
211 |
+
if (type == ";") return cont();
|
212 |
+
if (type == "function") return cont(functiondef);
|
213 |
+
if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
|
214 |
+
poplex, statement, poplex);
|
215 |
+
if (type == "variable") return cont(pushlex("stat"), maybelabel);
|
216 |
+
if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
|
217 |
+
block, poplex, poplex);
|
218 |
+
if (type == "case") return cont(expression, expect(":"));
|
219 |
+
if (type == "default") return cont(expect(":"));
|
220 |
+
if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
|
221 |
+
statement, poplex, popcontext);
|
222 |
+
return pass(pushlex("stat"), expression, expect(";"), poplex);
|
223 |
+
}
|
224 |
+
function expression(type) {
|
225 |
+
if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
|
226 |
+
if (type == "function") return cont(functiondef);
|
227 |
+
if (type == "keyword c") return cont(expression);
|
228 |
+
if (type == "(") return cont(pushlex(")"), expression, expect(")"), poplex, maybeoperator);
|
229 |
+
if (type == "operator") return cont(expression);
|
230 |
+
if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
|
231 |
+
if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
|
232 |
+
return cont();
|
233 |
+
}
|
234 |
+
function maybeoperator(type, value) {
|
235 |
+
if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator);
|
236 |
+
if (type == "operator") return cont(expression);
|
237 |
+
if (type == ";") return;
|
238 |
+
if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);
|
239 |
+
if (type == ".") return cont(property, maybeoperator);
|
240 |
+
if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
|
241 |
+
}
|
242 |
+
function maybelabel(type) {
|
243 |
+
if (type == ":") return cont(poplex, statement);
|
244 |
+
return pass(maybeoperator, expect(";"), poplex);
|
245 |
+
}
|
246 |
+
function property(type) {
|
247 |
+
if (type == "variable") {cx.marked = "property"; return cont();}
|
248 |
+
}
|
249 |
+
function objprop(type) {
|
250 |
+
if (type == "variable") cx.marked = "property";
|
251 |
+
if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression);
|
252 |
+
}
|
253 |
+
function commasep(what, end) {
|
254 |
+
function proceed(type) {
|
255 |
+
if (type == ",") return cont(what, proceed);
|
256 |
+
if (type == end) return cont();
|
257 |
+
return cont(expect(end));
|
258 |
+
}
|
259 |
+
return function commaSeparated(type) {
|
260 |
+
if (type == end) return cont();
|
261 |
+
else return pass(what, proceed);
|
262 |
+
};
|
263 |
+
}
|
264 |
+
function block(type) {
|
265 |
+
if (type == "}") return cont();
|
266 |
+
return pass(statement, block);
|
267 |
+
}
|
268 |
+
function vardef1(type, value) {
|
269 |
+
if (type == "variable"){register(value); return cont(vardef2);}
|
270 |
+
return cont();
|
271 |
+
}
|
272 |
+
function vardef2(type, value) {
|
273 |
+
if (value == "=") return cont(expression, vardef2);
|
274 |
+
if (type == ",") return cont(vardef1);
|
275 |
+
}
|
276 |
+
function forspec1(type) {
|
277 |
+
if (type == "var") return cont(vardef1, forspec2);
|
278 |
+
if (type == ";") return pass(forspec2);
|
279 |
+
if (type == "variable") return cont(formaybein);
|
280 |
+
return pass(forspec2);
|
281 |
+
}
|
282 |
+
function formaybein(type, value) {
|
283 |
+
if (value == "in") return cont(expression);
|
284 |
+
return cont(maybeoperator, forspec2);
|
285 |
+
}
|
286 |
+
function forspec2(type, value) {
|
287 |
+
if (type == ";") return cont(forspec3);
|
288 |
+
if (value == "in") return cont(expression);
|
289 |
+
return cont(expression, expect(";"), forspec3);
|
290 |
+
}
|
291 |
+
function forspec3(type) {
|
292 |
+
if (type != ")") cont(expression);
|
293 |
+
}
|
294 |
+
function functiondef(type, value) {
|
295 |
+
if (type == "variable") {register(value); return cont(functiondef);}
|
296 |
+
if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext);
|
297 |
+
}
|
298 |
+
function funarg(type, value) {
|
299 |
+
if (type == "variable") {register(value); return cont();}
|
300 |
+
}
|
301 |
+
|
302 |
+
// Interface
|
303 |
+
|
304 |
+
return {
|
305 |
+
startState: function(basecolumn) {
|
306 |
+
return {
|
307 |
+
tokenize: jsTokenBase,
|
308 |
+
reAllowed: true,
|
309 |
+
cc: [],
|
310 |
+
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
|
311 |
+
localVars: null,
|
312 |
+
context: null,
|
313 |
+
indented: 0
|
314 |
+
};
|
315 |
+
},
|
316 |
+
|
317 |
+
token: function(stream, state) {
|
318 |
+
if (stream.sol()) {
|
319 |
+
if (!state.lexical.hasOwnProperty("align"))
|
320 |
+
state.lexical.align = false;
|
321 |
+
state.indented = stream.indentation();
|
322 |
+
}
|
323 |
+
if (stream.eatSpace()) return null;
|
324 |
+
var style = state.tokenize(stream, state);
|
325 |
+
if (type == "comment") return style;
|
326 |
+
state.reAllowed = type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/);
|
327 |
+
return parseJS(state, style, type, content, stream);
|
328 |
+
},
|
329 |
+
|
330 |
+
indent: function(state, textAfter) {
|
331 |
+
if (state.tokenize != jsTokenBase) return 0;
|
332 |
+
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical,
|
333 |
+
type = lexical.type, closing = firstChar == type;
|
334 |
+
if (type == "vardef") return lexical.indented + 4;
|
335 |
+
else if (type == "form" && firstChar == "{") return lexical.indented;
|
336 |
+
else if (type == "stat" || type == "form") return lexical.indented + indentUnit;
|
337 |
+
else if (lexical.info == "switch" && !closing)
|
338 |
+
return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
|
339 |
+
else if (lexical.align) return lexical.column + (closing ? 0 : 1);
|
340 |
+
else return lexical.indented + (closing ? 0 : indentUnit);
|
341 |
+
},
|
342 |
+
|
343 |
+
electricChars: ":{}"
|
344 |
+
};
|
345 |
+
});
|
346 |
+
|
347 |
+
CodeMirror.defineMIME("text/javascript", "javascript");
|
348 |
+
CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
|
tinymce-plugins/cmseditor/js/mode/php/index.html
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!doctype html>
|
2 |
+
<html>
|
3 |
+
<head>
|
4 |
+
<title>CodeMirror 2: PHP mode</title>
|
5 |
+
<link rel="stylesheet" href="../../lib/codemirror.css">
|
6 |
+
<script src="../../lib/codemirror.js"></script>
|
7 |
+
<script src="../xml/xml.js"></script>
|
8 |
+
<script src="../javascript/javascript.js"></script>
|
9 |
+
<script src="../css/css.js"></script>
|
10 |
+
<script src="../clike/clike.js"></script>
|
11 |
+
<script src="php.js"></script>
|
12 |
+
<link rel="stylesheet" href="../../theme/default.css">
|
13 |
+
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
14 |
+
<link rel="stylesheet" href="../../css/docs.css">
|
15 |
+
</head>
|
16 |
+
<body>
|
17 |
+
<h1>CodeMirror 2: PHP mode</h1>
|
18 |
+
|
19 |
+
<form><textarea id="code" name="code">
|
20 |
+
<?php
|
21 |
+
function hello($who) {
|
22 |
+
return "Hello " . $who;
|
23 |
+
}
|
24 |
+
?>
|
25 |
+
<p>The program says <?= hello("World") ?>.</p>
|
26 |
+
<script>
|
27 |
+
alert("And here is some JS code"); // also colored
|
28 |
+
</script>
|
29 |
+
</textarea></form>
|
30 |
+
|
31 |
+
<script>
|
32 |
+
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
33 |
+
lineNumbers: true,
|
34 |
+
matchBrackets: true,
|
35 |
+
mode: "application/x-httpd-php",
|
36 |
+
indentUnit: 8,
|
37 |
+
indentWithTabs: true,
|
38 |
+
enterMode: "keep",
|
39 |
+
tabMode: "shift"
|
40 |
+
});
|
41 |
+
</script>
|
42 |
+
|
43 |
+
<p>Simple HTML/PHP mode based on
|
44 |
+
the <a href="../clike/">C-like</a> mode. Depends on XML,
|
45 |
+
JavaScript, CSS, and C-like modes.</p>
|
46 |
+
|
47 |
+
<p><strong>MIME types defined:</strong> <code>application/x-httpd-php</code> (HTML with PHP code), <code>text/x-php</code> (plain, non-wrapped PHP code).</p>
|
48 |
+
</body>
|
49 |
+
</html>
|
tinymce-plugins/cmseditor/js/mode/php/php.js
ADDED
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
(function() {
|
2 |
+
function keywords(str) {
|
3 |
+
var obj = {}, words = str.split(" ");
|
4 |
+
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
|
5 |
+
return obj;
|
6 |
+
}
|
7 |
+
function heredoc(delim) {
|
8 |
+
return function(stream, state) {
|
9 |
+
if (stream.match(delim)) state.tokenize = null;
|
10 |
+
else stream.skipToEnd();
|
11 |
+
return "string";
|
12 |
+
}
|
13 |
+
}
|
14 |
+
var phpConfig = {
|
15 |
+
name: "clike",
|
16 |
+
keywords: keywords("abstract and array as break case catch cfunction class clone const continue declare " +
|
17 |
+
"default do else elseif enddeclare endfor endforeach endif endswitch endwhile extends " +
|
18 |
+
"final for foreach function global goto if implements interface instanceof namespace " +
|
19 |
+
"new or private protected public static switch throw try use var while xor return"),
|
20 |
+
blockKeywords: keywords("catch do else elseif for foreach if switch try while"),
|
21 |
+
atoms: keywords("true false null"),
|
22 |
+
multiLineStrings: true,
|
23 |
+
hooks: {
|
24 |
+
"$": function(stream, state) {
|
25 |
+
stream.eatWhile(/[\w\$_]/);
|
26 |
+
return "variable-2";
|
27 |
+
},
|
28 |
+
"<": function(stream, state) {
|
29 |
+
if (stream.match(/<</)) {
|
30 |
+
stream.eatWhile(/[\w\.]/);
|
31 |
+
state.tokenize = heredoc(stream.current().slice(3));
|
32 |
+
return state.tokenize(stream, state);
|
33 |
+
}
|
34 |
+
return false;
|
35 |
+
}
|
36 |
+
}
|
37 |
+
};
|
38 |
+
|
39 |
+
CodeMirror.defineMode("php", function(config, parserConfig) {
|
40 |
+
var htmlMode = CodeMirror.getMode(config, "text/html");
|
41 |
+
var jsMode = CodeMirror.getMode(config, "text/javascript");
|
42 |
+
var cssMode = CodeMirror.getMode(config, "text/css");
|
43 |
+
var phpMode = CodeMirror.getMode(config, phpConfig);
|
44 |
+
|
45 |
+
function dispatch(stream, state) { // TODO open PHP inside text/css
|
46 |
+
if (state.curMode == htmlMode) {
|
47 |
+
var style = htmlMode.token(stream, state.curState);
|
48 |
+
if (style == "meta" && /^<\?/.test(stream.current())) {
|
49 |
+
state.curMode = phpMode;
|
50 |
+
state.curState = state.php;
|
51 |
+
state.curClose = /^\?>/;
|
52 |
+
state.mode = 'php';
|
53 |
+
}
|
54 |
+
else if (style == "tag" && stream.current() == ">" && state.curState.context) {
|
55 |
+
if (/^script$/i.test(state.curState.context.tagName)) {
|
56 |
+
state.curMode = jsMode;
|
57 |
+
state.curState = jsMode.startState(htmlMode.indent(state.curState, ""));
|
58 |
+
state.curClose = /^<\/\s*script\s*>/i;
|
59 |
+
state.mode = 'javascript';
|
60 |
+
}
|
61 |
+
else if (/^style$/i.test(state.curState.context.tagName)) {
|
62 |
+
state.curMode = cssMode;
|
63 |
+
state.curState = cssMode.startState(htmlMode.indent(state.curState, ""));
|
64 |
+
state.curClose = /^<\/\s*style\s*>/i;
|
65 |
+
state.mode = 'css';
|
66 |
+
}
|
67 |
+
}
|
68 |
+
return style;
|
69 |
+
}
|
70 |
+
else if (stream.match(state.curClose, false)) {
|
71 |
+
state.curMode = htmlMode;
|
72 |
+
state.curState = state.html;
|
73 |
+
state.curClose = null;
|
74 |
+
state.mode = 'html';
|
75 |
+
return dispatch(stream, state);
|
76 |
+
}
|
77 |
+
else return state.curMode.token(stream, state.curState);
|
78 |
+
}
|
79 |
+
|
80 |
+
return {
|
81 |
+
startState: function() {
|
82 |
+
var html = htmlMode.startState();
|
83 |
+
return {html: html,
|
84 |
+
php: phpMode.startState(),
|
85 |
+
curMode: parserConfig.startOpen ? phpMode : htmlMode,
|
86 |
+
curState: parserConfig.startOpen ? phpMode.startState() : html,
|
87 |
+
curClose: parserConfig.startOpen ? /^\?>/ : null,
|
88 |
+
mode: parserConfig.startOpen ? 'php' : 'html'}
|
89 |
+
},
|
90 |
+
|
91 |
+
copyState: function(state) {
|
92 |
+
var html = state.html, htmlNew = CodeMirror.copyState(htmlMode, html),
|
93 |
+
php = state.php, phpNew = CodeMirror.copyState(phpMode, php), cur;
|
94 |
+
if (state.curState == html) cur = htmlNew;
|
95 |
+
else if (state.curState == php) cur = phpNew;
|
96 |
+
else cur = CodeMirror.copyState(state.curMode, state.curState);
|
97 |
+
return {html: htmlNew, php: phpNew, curMode: state.curMode, curState: cur, curClose: state.curClose};
|
98 |
+
},
|
99 |
+
|
100 |
+
token: dispatch,
|
101 |
+
|
102 |
+
indent: function(state, textAfter) {
|
103 |
+
if ((state.curMode != phpMode && /^\s*<\//.test(textAfter)) ||
|
104 |
+
(state.curMode == phpMode && /^\?>/.test(textAfter)))
|
105 |
+
return htmlMode.indent(state.html, textAfter);
|
106 |
+
return state.curMode.indent(state.curState, textAfter);
|
107 |
+
},
|
108 |
+
|
109 |
+
electricChars: "/{}:"
|
110 |
+
}
|
111 |
+
});
|
112 |
+
CodeMirror.defineMIME("application/x-httpd-php", "php");
|
113 |
+
CodeMirror.defineMIME("application/x-httpd-php-open", {name: "php", startOpen: true});
|
114 |
+
CodeMirror.defineMIME("text/x-php", phpConfig);
|
115 |
+
})();
|
tinymce-plugins/cmseditor/js/mode/xml/index.html
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!doctype html>
|
2 |
+
<html>
|
3 |
+
<head>
|
4 |
+
<title>CodeMirror 2: XML mode</title>
|
5 |
+
<link rel="stylesheet" href="../../lib/codemirror.css">
|
6 |
+
<script src="../../lib/codemirror.js"></script>
|
7 |
+
<script src="xml.js"></script>
|
8 |
+
<link rel="stylesheet" href="../../theme/default.css">
|
9 |
+
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
10 |
+
<link rel="stylesheet" href="../../css/docs.css">
|
11 |
+
</head>
|
12 |
+
<body>
|
13 |
+
<h1>CodeMirror 2: XML mode</h1>
|
14 |
+
<form><textarea id="code" name="code">
|
15 |
+
<html style="color: green">
|
16 |
+
<!-- this is a comment -->
|
17 |
+
<head>
|
18 |
+
<title>HTML Example</title>
|
19 |
+
</head>
|
20 |
+
<body>
|
21 |
+
The indentation tries to be <em>somewhat &quot;do what
|
22 |
+
I mean&quot;</em>... but might not match your style.
|
23 |
+
</body>
|
24 |
+
</html>
|
25 |
+
</textarea></form>
|
26 |
+
<script>
|
27 |
+
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: {name: "xml", htmlMode: true}});
|
28 |
+
</script>
|
29 |
+
<p>The XML mode supports two configuration parameters:</p>
|
30 |
+
<dl>
|
31 |
+
<dt><code>htmlMode (boolean)</code></dt>
|
32 |
+
<dd>This switches the mode to parse HTML instead of XML. This
|
33 |
+
means attributes do not have to be quoted, and some elements
|
34 |
+
(such as <code>br</code>) do not require a closing tag.</dd>
|
35 |
+
<dt><code>alignCDATA (boolean)</code></dt>
|
36 |
+
<dd>Setting this to true will force the opening tag of CDATA
|
37 |
+
blocks to not be indented.</dd>
|
38 |
+
</dl>
|
39 |
+
|
40 |
+
<p><strong>MIME types defined:</strong> <code>application/xml</code>, <code>text/html</code>.</p>
|
41 |
+
</body>
|
42 |
+
</html>
|
tinymce-plugins/cmseditor/js/mode/xml/xml.js
ADDED
@@ -0,0 +1,231 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
CodeMirror.defineMode("xml", function(config, parserConfig) {
|
2 |
+
var indentUnit = config.indentUnit;
|
3 |
+
var Kludges = parserConfig.htmlMode ? {
|
4 |
+
autoSelfClosers: {"br": true, "img": true, "hr": true, "link": true, "input": true,
|
5 |
+
"meta": true, "col": true, "frame": true, "base": true, "area": true},
|
6 |
+
doNotIndent: {"pre": true, "!cdata": true},
|
7 |
+
allowUnquoted: true
|
8 |
+
} : {autoSelfClosers: {}, doNotIndent: {"!cdata": true}, allowUnquoted: false};
|
9 |
+
var alignCDATA = parserConfig.alignCDATA;
|
10 |
+
|
11 |
+
// Return variables for tokenizers
|
12 |
+
var tagName, type;
|
13 |
+
|
14 |
+
function inText(stream, state) {
|
15 |
+
function chain(parser) {
|
16 |
+
state.tokenize = parser;
|
17 |
+
return parser(stream, state);
|
18 |
+
}
|
19 |
+
|
20 |
+
var ch = stream.next();
|
21 |
+
if (ch == "<") {
|
22 |
+
if (stream.eat("!")) {
|
23 |
+
if (stream.eat("[")) {
|
24 |
+
if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
|
25 |
+
else return null;
|
26 |
+
}
|
27 |
+
else if (stream.match("--")) return chain(inBlock("comment", "-->"));
|
28 |
+
else if (stream.match("DOCTYPE", true, true)) {
|
29 |
+
stream.eatWhile(/[\w\._\-]/);
|
30 |
+
return chain(inBlock("meta", ">"));
|
31 |
+
}
|
32 |
+
else return null;
|
33 |
+
}
|
34 |
+
else if (stream.eat("?")) {
|
35 |
+
stream.eatWhile(/[\w\._\-]/);
|
36 |
+
state.tokenize = inBlock("meta", "?>");
|
37 |
+
return "meta";
|
38 |
+
}
|
39 |
+
else {
|
40 |
+
type = stream.eat("/") ? "closeTag" : "openTag";
|
41 |
+
stream.eatSpace();
|
42 |
+
tagName = "";
|
43 |
+
var c;
|
44 |
+
while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
|
45 |
+
state.tokenize = inTag;
|
46 |
+
return "tag";
|
47 |
+
}
|
48 |
+
}
|
49 |
+
else if (ch == "&") {
|
50 |
+
stream.eatWhile(/[^;]/);
|
51 |
+
stream.eat(";");
|
52 |
+
return "atom";
|
53 |
+
}
|
54 |
+
else {
|
55 |
+
stream.eatWhile(/[^&<]/);
|
56 |
+
return null;
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
function inTag(stream, state) {
|
61 |
+
var ch = stream.next();
|
62 |
+
if (ch == ">" || (ch == "/" && stream.eat(">"))) {
|
63 |
+
state.tokenize = inText;
|
64 |
+
type = ch == ">" ? "endTag" : "selfcloseTag";
|
65 |
+
return "tag";
|
66 |
+
}
|
67 |
+
else if (ch == "=") {
|
68 |
+
type = "equals";
|
69 |
+
return null;
|
70 |
+
}
|
71 |
+
else if (/[\'\"]/.test(ch)) {
|
72 |
+
state.tokenize = inAttribute(ch);
|
73 |
+
return state.tokenize(stream, state);
|
74 |
+
}
|
75 |
+
else {
|
76 |
+
stream.eatWhile(/[^\s\u00a0=<>\"\'\/?]/);
|
77 |
+
return "word";
|
78 |
+
}
|
79 |
+
}
|
80 |
+
|
81 |
+
function inAttribute(quote) {
|
82 |
+
return function(stream, state) {
|
83 |
+
while (!stream.eol()) {
|
84 |
+
if (stream.next() == quote) {
|
85 |
+
state.tokenize = inTag;
|
86 |
+
break;
|
87 |
+
}
|
88 |
+
}
|
89 |
+
return "string";
|
90 |
+
};
|
91 |
+
}
|
92 |
+
|
93 |
+
function inBlock(style, terminator) {
|
94 |
+
return function(stream, state) {
|
95 |
+
while (!stream.eol()) {
|
96 |
+
if (stream.match(terminator)) {
|
97 |
+
state.tokenize = inText;
|
98 |
+
break;
|
99 |
+
}
|
100 |
+
stream.next();
|
101 |
+
}
|
102 |
+
return style;
|
103 |
+
};
|
104 |
+
}
|
105 |
+
|
106 |
+
var curState, setStyle;
|
107 |
+
function pass() {
|
108 |
+
for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
|
109 |
+
}
|
110 |
+
function cont() {
|
111 |
+
pass.apply(null, arguments);
|
112 |
+
return true;
|
113 |
+
}
|
114 |
+
|
115 |
+
function pushContext(tagName, startOfLine) {
|
116 |
+
var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent);
|
117 |
+
curState.context = {
|
118 |
+
prev: curState.context,
|
119 |
+
tagName: tagName,
|
120 |
+
indent: curState.indented,
|
121 |
+
startOfLine: startOfLine,
|
122 |
+
noIndent: noIndent
|
123 |
+
};
|
124 |
+
}
|
125 |
+
function popContext() {
|
126 |
+
if (curState.context) curState.context = curState.context.prev;
|
127 |
+
}
|
128 |
+
|
129 |
+
function element(type) {
|
130 |
+
if (type == "openTag") {curState.tagName = tagName; return cont(attributes, endtag(curState.startOfLine));}
|
131 |
+
else if (type == "closeTag") {
|
132 |
+
var err = false;
|
133 |
+
if (curState.context) {
|
134 |
+
err = curState.context.tagName != tagName;
|
135 |
+
popContext();
|
136 |
+
} else {
|
137 |
+
err = true;
|
138 |
+
}
|
139 |
+
if (err) setStyle = "error";
|
140 |
+
return cont(endclosetag(err));
|
141 |
+
}
|
142 |
+
else if (type == "string") {
|
143 |
+
if (!curState.context || curState.context.name != "!cdata") pushContext("!cdata");
|
144 |
+
if (curState.tokenize == inText) popContext();
|
145 |
+
return cont();
|
146 |
+
}
|
147 |
+
else return cont();
|
148 |
+
}
|
149 |
+
function endtag(startOfLine) {
|
150 |
+
return function(type) {
|
151 |
+
if (type == "selfcloseTag" ||
|
152 |
+
(type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(curState.tagName.toLowerCase())))
|
153 |
+
return cont();
|
154 |
+
if (type == "endTag") {pushContext(curState.tagName, startOfLine); return cont();}
|
155 |
+
return cont();
|
156 |
+
};
|
157 |
+
}
|
158 |
+
function endclosetag(err) {
|
159 |
+
return function(type) {
|
160 |
+
if (err) setStyle = "error";
|
161 |
+
if (type == "endTag") return cont();
|
162 |
+
return pass();
|
163 |
+
}
|
164 |
+
}
|
165 |
+
|
166 |
+
function attributes(type) {
|
167 |
+
if (type == "word") {setStyle = "attribute"; return cont(attributes);}
|
168 |
+
if (type == "equals") return cont(attvalue, attributes);
|
169 |
+
return pass();
|
170 |
+
}
|
171 |
+
function attvalue(type) {
|
172 |
+
if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();}
|
173 |
+
if (type == "string") return cont(attvaluemaybe);
|
174 |
+
return pass();
|
175 |
+
}
|
176 |
+
function attvaluemaybe(type) {
|
177 |
+
if (type == "string") return cont(attvaluemaybe);
|
178 |
+
else return pass();
|
179 |
+
}
|
180 |
+
|
181 |
+
return {
|
182 |
+
startState: function() {
|
183 |
+
return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, context: null};
|
184 |
+
},
|
185 |
+
|
186 |
+
token: function(stream, state) {
|
187 |
+
if (stream.sol()) {
|
188 |
+
state.startOfLine = true;
|
189 |
+
state.indented = stream.indentation();
|
190 |
+
}
|
191 |
+
if (stream.eatSpace()) return null;
|
192 |
+
|
193 |
+
setStyle = type = tagName = null;
|
194 |
+
var style = state.tokenize(stream, state);
|
195 |
+
if ((style || type) && style != "comment") {
|
196 |
+
curState = state;
|
197 |
+
while (true) {
|
198 |
+
var comb = state.cc.pop() || element;
|
199 |
+
if (comb(type || style)) break;
|
200 |
+
}
|
201 |
+
}
|
202 |
+
state.startOfLine = false;
|
203 |
+
return setStyle || style;
|
204 |
+
},
|
205 |
+
|
206 |
+
indent: function(state, textAfter) {
|
207 |
+
var context = state.context;
|
208 |
+
if (context && context.noIndent) return 0;
|
209 |
+
if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
|
210 |
+
if (context && /^<\//.test(textAfter))
|
211 |
+
context = context.prev;
|
212 |
+
while (context && !context.startOfLine)
|
213 |
+
context = context.prev;
|
214 |
+
if (context) return context.indent + indentUnit;
|
215 |
+
else return 0;
|
216 |
+
},
|
217 |
+
|
218 |
+
compareStates: function(a, b) {
|
219 |
+
if (a.indented != b.indented || a.tagName != b.tagName) return false;
|
220 |
+
for (var ca = a.context, cb = b.context; ; ca = ca.prev, cb = cb.prev) {
|
221 |
+
if (!ca || !cb) return ca == cb;
|
222 |
+
if (ca.tagName != cb.tagName) return false;
|
223 |
+
}
|
224 |
+
},
|
225 |
+
|
226 |
+
electricChars: "/"
|
227 |
+
};
|
228 |
+
});
|
229 |
+
|
230 |
+
CodeMirror.defineMIME("application/xml", "xml");
|
231 |
+
CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
|
tinymce-plugins/cmseditor/js/mode/xmlpure/index.html
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!doctype html>
|
2 |
+
<html>
|
3 |
+
<head>
|
4 |
+
<title>CodeMirror 2: Pure XML mode</title>
|
5 |
+
<link rel="stylesheet" href="../../lib/codemirror.css">
|
6 |
+
<script src="../../lib/codemirror.js"></script>
|
7 |
+
<script src="xmlpure.js"></script>
|
8 |
+
<link rel="stylesheet" href="../../theme/default.css">
|
9 |
+
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
10 |
+
<link rel="stylesheet" href="../../css/docs.css">
|
11 |
+
</head>
|
12 |
+
<body>
|
13 |
+
<h1>CodeMirror 2: XML mode</h1>
|
14 |
+
<form><textarea id="code" name="code">
|
15 |
+
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
16 |
+
|
17 |
+
<!-- This is the pure XML mode,
|
18 |
+
and we're inside a comment! -->
|
19 |
+
|
20 |
+
<catalog>
|
21 |
+
<books>
|
22 |
+
<book id="bk01">
|
23 |
+
<title>Lord of Light</title>
|
24 |
+
<author>Roger Zelazny</author>
|
25 |
+
<year>1967</year>
|
26 |
+
<description><![CDATA[This is a great book, really!!]]></description>
|
27 |
+
</book>
|
28 |
+
</books>
|
29 |
+
</catalog>
|
30 |
+
</textarea></form>
|
31 |
+
<script>
|
32 |
+
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {mode: {name: "xmlpure"}});
|
33 |
+
</script>
|
34 |
+
|
35 |
+
<p>This is my XML parser, based on the original:</p>
|
36 |
+
<ul>
|
37 |
+
<li>No html mode - this is pure xml</li>
|
38 |
+
<li>Illegal attributes and element names are errors</li>
|
39 |
+
<li>Attributes must have a value</li>
|
40 |
+
<li>XML declaration supported (e.g.: <b><?xml version="1.0" encoding="utf-8" standalone="no" ?></b>)</li>
|
41 |
+
<li>CDATA and comment blocks are not indented (except for their start-tag)</li>
|
42 |
+
<li>Better handling of errors per line with the state object - provides good infrastructure for extending it</li>
|
43 |
+
</ul>
|
44 |
+
|
45 |
+
<p>What's missing:</p>
|
46 |
+
<ul>
|
47 |
+
<li>Make sure only a single root element exists at the document level</li>
|
48 |
+
<li>Multi-line attributes should NOT indent</li>
|
49 |
+
<li>Start tags are not painted red when they have no matching end tags (is this really wrong?)</li>
|
50 |
+
</ul>
|
51 |
+
|
52 |
+
<p><strong>MIME types defined:</strong> <code>application/xml</code>, <code>text/xml</code>.</p>
|
53 |
+
|
54 |
+
<p><b>@author</b>: Dror BG (<i>deebug dot dev at gmail dot com</i>)<br/>
|
55 |
+
<p><b>@date</b>: August, 2011<br/>
|
56 |
+
<p><b>@github</b>: <a href='https://github.com/deebugger/CodeMirror2' target='blank'>https://github.com/deebugger/CodeMirror2</a></p>
|
57 |
+
|
58 |
+
<p><strong>MIME types defined:</strong> <code>application/xml</code>, <code>text/xml</code>.</p>
|
59 |
+
</body>
|
60 |
+
</html>
|
tinymce-plugins/cmseditor/js/mode/xmlpure/xmlpure.js
ADDED
@@ -0,0 +1,481 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* xmlpure.js
|
3 |
+
*
|
4 |
+
* Building upon and improving the CodeMirror 2 XML parser
|
5 |
+
* @author: Dror BG (deebug.dev@gmail.com)
|
6 |
+
* @date: August, 2011
|
7 |
+
*/
|
8 |
+
|
9 |
+
CodeMirror.defineMode("xmlpure", function(config, parserConfig) {
|
10 |
+
// constants
|
11 |
+
var STYLE_ERROR = "error";
|
12 |
+
var STYLE_INSTRUCTION = "comment";
|
13 |
+
var STYLE_COMMENT = "comment";
|
14 |
+
var STYLE_ELEMENT_NAME = "tag";
|
15 |
+
var STYLE_ATTRIBUTE = "attribute";
|
16 |
+
var STYLE_WORD = "string";
|
17 |
+
var STYLE_TEXT = "atom";
|
18 |
+
|
19 |
+
var TAG_INSTRUCTION = "!instruction";
|
20 |
+
var TAG_CDATA = "!cdata";
|
21 |
+
var TAG_COMMENT = "!comment";
|
22 |
+
var TAG_TEXT = "!text";
|
23 |
+
|
24 |
+
var doNotIndent = {
|
25 |
+
"!cdata": true,
|
26 |
+
"!comment": true,
|
27 |
+
"!text": true,
|
28 |
+
"!instruction": true
|
29 |
+
};
|
30 |
+
|
31 |
+
// options
|
32 |
+
var indentUnit = config.indentUnit;
|
33 |
+
|
34 |
+
///////////////////////////////////////////////////////////////////////////
|
35 |
+
// helper functions
|
36 |
+
|
37 |
+
// chain a parser to another parser
|
38 |
+
function chain(stream, state, parser) {
|
39 |
+
state.tokenize = parser;
|
40 |
+
return parser(stream, state);
|
41 |
+
}
|
42 |
+
|
43 |
+
// parse a block (comment, CDATA or text)
|
44 |
+
function inBlock(style, terminator, nextTokenize) {
|
45 |
+
return function(stream, state) {
|
46 |
+
while (!stream.eol()) {
|
47 |
+
if (stream.match(terminator)) {
|
48 |
+
popContext(state);
|
49 |
+
state.tokenize = nextTokenize;
|
50 |
+
break;
|
51 |
+
}
|
52 |
+
stream.next();
|
53 |
+
}
|
54 |
+
return style;
|
55 |
+
};
|
56 |
+
}
|
57 |
+
|
58 |
+
// go down a level in the document
|
59 |
+
// (hint: look at who calls this function to know what the contexts are)
|
60 |
+
function pushContext(state, tagName) {
|
61 |
+
var noIndent = doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.doIndent);
|
62 |
+
var newContext = {
|
63 |
+
tagName: tagName,
|
64 |
+
prev: state.context,
|
65 |
+
indent: state.context ? state.context.indent + indentUnit : 0,
|
66 |
+
lineNumber: state.lineNumber,
|
67 |
+
indented: state.indented,
|
68 |
+
noIndent: noIndent
|
69 |
+
};
|
70 |
+
state.context = newContext;
|
71 |
+
}
|
72 |
+
|
73 |
+
// go up a level in the document
|
74 |
+
function popContext(state) {
|
75 |
+
if (state.context) {
|
76 |
+
var oldContext = state.context;
|
77 |
+
state.context = oldContext.prev;
|
78 |
+
return oldContext;
|
79 |
+
}
|
80 |
+
|
81 |
+
// we shouldn't be here - it means we didn't have a context to pop
|
82 |
+
return null;
|
83 |
+
}
|
84 |
+
|
85 |
+
// return true if the current token is seperated from the tokens before it
|
86 |
+
// which means either this is the start of the line, or there is at least
|
87 |
+
// one space or tab character behind the token
|
88 |
+
// otherwise returns false
|
89 |
+
function isTokenSeparated(stream) {
|
90 |
+
return stream.sol() ||
|
91 |
+
stream.string.charAt(stream.start - 1) == " " ||
|
92 |
+
stream.string.charAt(stream.start - 1) == "\t";
|
93 |
+
}
|
94 |
+
|
95 |
+
///////////////////////////////////////////////////////////////////////////
|
96 |
+
// context: document
|
97 |
+
//
|
98 |
+
// an XML document can contain:
|
99 |
+
// - a single declaration (if defined, it must be the very first line)
|
100 |
+
// - exactly one root element
|
101 |
+
// @todo try to actually limit the number of root elements to 1
|
102 |
+
// - zero or more comments
|
103 |
+
function parseDocument(stream, state) {
|
104 |
+
if(stream.eat("<")) {
|
105 |
+
if(stream.eat("?")) {
|
106 |
+
// processing instruction
|
107 |
+
pushContext(state, TAG_INSTRUCTION);
|
108 |
+
state.tokenize = parseProcessingInstructionStartTag;
|
109 |
+
return STYLE_INSTRUCTION;
|
110 |
+
} else if(stream.match("!--")) {
|
111 |
+
// new context: comment
|
112 |
+
pushContext(state, TAG_COMMENT);
|
113 |
+
return chain(stream, state, inBlock(STYLE_COMMENT, "-->", parseDocument));
|
114 |
+
} else if(stream.eatSpace() || stream.eol() ) {
|
115 |
+
stream.skipToEnd();
|
116 |
+
return STYLE_ERROR;
|
117 |
+
} else {
|
118 |
+
// element
|
119 |
+
state.tokenize = parseElementTagName;
|
120 |
+
return STYLE_ELEMENT_NAME;
|
121 |
+
}
|
122 |
+
}
|
123 |
+
|
124 |
+
// error on line
|
125 |
+
stream.skipToEnd();
|
126 |
+
return STYLE_ERROR;
|
127 |
+
}
|
128 |
+
|
129 |
+
///////////////////////////////////////////////////////////////////////////
|
130 |
+
// context: XML element start-tag or end-tag
|
131 |
+
//
|
132 |
+
// - element start-tag can contain attributes
|
133 |
+
// - element start-tag may self-close (or start an element block if it doesn't)
|
134 |
+
// - element end-tag can contain only the tag name
|
135 |
+
function parseElementTagName(stream, state) {
|
136 |
+
// get the name of the tag
|
137 |
+
var startPos = stream.pos;
|
138 |
+
if(stream.match(/^[a-zA-Z_:][-a-zA-Z0-9_:.]*/)) {
|
139 |
+
// element start-tag
|
140 |
+
var tagName = stream.string.substring(startPos, stream.pos);
|
141 |
+
pushContext(state, tagName);
|
142 |
+
state.tokenize = parseElement;
|
143 |
+
return STYLE_ELEMENT_NAME;
|
144 |
+
} else if(stream.match(/^\/[a-zA-Z_:][-a-zA-Z0-9_:.]*( )*>/)) {
|
145 |
+
// element end-tag
|
146 |
+
var endTagName = stream.string.substring(startPos + 1, stream.pos - 1).trim();
|
147 |
+
var oldContext = popContext(state);
|
148 |
+
state.tokenize = state.context == null ? parseDocument : parseElementBlock;
|
149 |
+
if(oldContext == null || endTagName != oldContext.tagName) {
|
150 |
+
// the start and end tag names should match - error
|
151 |
+
return STYLE_ERROR;
|
152 |
+
}
|
153 |
+
return STYLE_ELEMENT_NAME;
|
154 |
+
} else {
|
155 |
+
// no tag name - error
|
156 |
+
state.tokenize = state.context == null ? parseDocument : parseElementBlock;
|
157 |
+
stream.eatWhile(/[^>]/);
|
158 |
+
stream.eat(">");
|
159 |
+
return STYLE_ERROR;
|
160 |
+
}
|
161 |
+
|
162 |
+
stream.skipToEnd();
|
163 |
+
return null;
|
164 |
+
}
|
165 |
+
|
166 |
+
function parseElement(stream, state) {
|
167 |
+
if(stream.match(/^\/>/)) {
|
168 |
+
// self-closing tag
|
169 |
+
popContext(state);
|
170 |
+
state.tokenize = state.context == null ? parseDocument : parseElementBlock;
|
171 |
+
return STYLE_ELEMENT_NAME;
|
172 |
+
} else if(stream.eat(/^>/)) {
|
173 |
+
state.tokenize = parseElementBlock;
|
174 |
+
return STYLE_ELEMENT_NAME;
|
175 |
+
} else if(isTokenSeparated(stream) && stream.match(/^[a-zA-Z_:][-a-zA-Z0-9_:.]*( )*=/)) {
|
176 |
+
// attribute
|
177 |
+
state.tokenize = parseAttribute;
|
178 |
+
return STYLE_ATTRIBUTE;
|
179 |
+
}
|
180 |
+
|
181 |
+
// no other options - this is an error
|
182 |
+
state.tokenize = state.context == null ? parseDocument : parseDocument;
|
183 |
+
stream.eatWhile(/[^>]/);
|
184 |
+
stream.eat(">");
|
185 |
+
return STYLE_ERROR;
|
186 |
+
}
|
187 |
+
|
188 |
+
///////////////////////////////////////////////////////////////////////////
|
189 |
+
// context: attribute
|
190 |
+
//
|
191 |
+
// attribute values may contain everything, except:
|
192 |
+
// - the ending quote (with ' or ") - this marks the end of the value
|
193 |
+
// - the character "<" - should never appear
|
194 |
+
// - ampersand ("&") - unless it starts a reference: a string that ends with a semi-colon (";")
|
195 |
+
// ---> note: this parser is lax in what may be put into a reference string,
|
196 |
+
// ---> consult http://www.w3.org/TR/REC-xml/#NT-Reference if you want to make it tighter
|
197 |
+
function parseAttribute(stream, state) {
|
198 |
+
var quote = stream.next();
|
199 |
+
if(quote != "\"" && quote != "'") {
|
200 |
+
// attribute must be quoted
|
201 |
+
stream.skipToEnd();
|
202 |
+
state.tokenize = parseElement;
|
203 |
+
return STYLE_ERROR;
|
204 |
+
}
|
205 |
+
|
206 |
+
state.tokParams.quote = quote;
|
207 |
+
state.tokenize = parseAttributeValue;
|
208 |
+
return STYLE_WORD;
|
209 |
+
}
|
210 |
+
|
211 |
+
// @todo: find out whether this attribute value spans multiple lines,
|
212 |
+
// and if so, push a context for it in order not to indent it
|
213 |
+
// (or something of the sort..)
|
214 |
+
function parseAttributeValue(stream, state) {
|
215 |
+
var ch = "";
|
216 |
+
while(!stream.eol()) {
|
217 |
+
ch = stream.next();
|
218 |
+
if(ch == state.tokParams.quote) {
|
219 |
+
// end quote found
|
220 |
+
state.tokenize = parseElement;
|
221 |
+
return STYLE_WORD;
|
222 |
+
} else if(ch == "<") {
|
223 |
+
// can't have less-than signs in an attribute value, ever
|
224 |
+
stream.skipToEnd()
|
225 |
+
state.tokenize = parseElement;
|
226 |
+
return STYLE_ERROR;
|
227 |
+
} else if(ch == "&") {
|
228 |
+
// reference - look for a semi-colon, or return error if none found
|
229 |
+
ch = stream.next();
|
230 |
+
|
231 |
+
// make sure that semi-colon isn't right after the ampersand
|
232 |
+
if(ch == ';') {
|
233 |
+
stream.skipToEnd()
|
234 |
+
state.tokenize = parseElement;
|
235 |
+
return STYLE_ERROR;
|
236 |
+
}
|
237 |
+
|
238 |
+
// make sure no less-than characters slipped in
|
239 |
+
while(!stream.eol() && ch != ";") {
|
240 |
+
if(ch == "<") {
|
241 |
+
// can't have less-than signs in an attribute value, ever
|
242 |
+
stream.skipToEnd()
|
243 |
+
state.tokenize = parseElement;
|
244 |
+
return STYLE_ERROR;
|
245 |
+
}
|
246 |
+
ch = stream.next();
|
247 |
+
}
|
248 |
+
if(stream.eol() && ch != ";") {
|
249 |
+
// no ampersand found - error
|
250 |
+
stream.skipToEnd();
|
251 |
+
state.tokenize = parseElement;
|
252 |
+
return STYLE_ERROR;
|
253 |
+
}
|
254 |
+
}
|
255 |
+
}
|
256 |
+
|
257 |
+
// attribute value continues to next line
|
258 |
+
return STYLE_WORD;
|
259 |
+
}
|
260 |
+
|
261 |
+
///////////////////////////////////////////////////////////////////////////
|
262 |
+
// context: element block
|
263 |
+
//
|
264 |
+
// a block can contain:
|
265 |
+
// - elements
|
266 |
+
// - text
|
267 |
+
// - CDATA sections
|
268 |
+
// - comments
|
269 |
+
function parseElementBlock(stream, state) {
|
270 |
+
if(stream.eat("<")) {
|
271 |
+
if(stream.match("?")) {
|
272 |
+
pushContext(state, TAG_INSTRUCTION);
|
273 |
+
state.tokenize = parseProcessingInstructionStartTag;
|
274 |
+
return STYLE_INSTRUCTION;
|
275 |
+
} else if(stream.match("!--")) {
|
276 |
+
// new context: comment
|
277 |
+
pushContext(state, TAG_COMMENT);
|
278 |
+
return chain(stream, state, inBlock(STYLE_COMMENT, "-->",
|
279 |
+
state.context == null ? parseDocument : parseElementBlock));
|
280 |
+
} else if(stream.match("![CDATA[")) {
|
281 |
+
// new context: CDATA section
|
282 |
+
pushContext(state, TAG_CDATA);
|
283 |
+
return chain(stream, state, inBlock(STYLE_TEXT, "]]>",
|
284 |
+
state.context == null ? parseDocument : parseElementBlock));
|
285 |
+
} else if(stream.eatSpace() || stream.eol() ) {
|
286 |
+
stream.skipToEnd();
|
287 |
+
return STYLE_ERROR;
|
288 |
+
} else {
|
289 |
+
// element
|
290 |
+
state.tokenize = parseElementTagName;
|
291 |
+
return STYLE_ELEMENT_NAME;
|
292 |
+
}
|
293 |
+
} else {
|
294 |
+
// new context: text
|
295 |
+
pushContext(state, TAG_TEXT);
|
296 |
+
state.tokenize = parseText;
|
297 |
+
return null;
|
298 |
+
}
|
299 |
+
|
300 |
+
state.tokenize = state.context == null ? parseDocument : parseElementBlock;
|
301 |
+
stream.skipToEnd();
|
302 |
+
return null;
|
303 |
+
}
|
304 |
+
|
305 |
+
function parseText(stream, state) {
|
306 |
+
stream.eatWhile(/[^<]/);
|
307 |
+
if(!stream.eol()) {
|
308 |
+
// we cannot possibly be in the document context,
|
309 |
+
// just inside an element block
|
310 |
+
popContext(state);
|
311 |
+
state.tokenize = parseElementBlock;
|
312 |
+
}
|
313 |
+
return STYLE_TEXT;
|
314 |
+
}
|
315 |
+
|
316 |
+
///////////////////////////////////////////////////////////////////////////
|
317 |
+
// context: XML processing instructions
|
318 |
+
//
|
319 |
+
// XML processing instructions (PIs) allow documents to contain instructions for applications.
|
320 |
+
// PI format: <?name data?>
|
321 |
+
// - 'name' can be anything other than 'xml' (case-insensitive)
|
322 |
+
// - 'data' can be anything which doesn't contain '?>'
|
323 |
+
// XML declaration is a special PI (see XML declaration context below)
|
324 |
+
function parseProcessingInstructionStartTag(stream, state) {
|
325 |
+
if(stream.match("xml", true, true)) {
|
326 |
+
// xml declaration
|
327 |
+
if(state.lineNumber > 1 || stream.pos > 5) {
|
328 |
+
state.tokenize = parseDocument;
|
329 |
+
stream.skipToEnd();
|
330 |
+
return STYLE_ERROR;
|
331 |
+
} else {
|
332 |
+
state.tokenize = parseDeclarationVersion;
|
333 |
+
return STYLE_INSTRUCTION;
|
334 |
+
}
|
335 |
+
}
|
336 |
+
|
337 |
+
// regular processing instruction
|
338 |
+
if(isTokenSeparated(stream) || stream.match("?>")) {
|
339 |
+
// we have a space after the start-tag, or nothing but the end-tag
|
340 |
+
// either way - error!
|
341 |
+
state.tokenize = parseDocument;
|
342 |
+
stream.skipToEnd();
|
343 |
+
return STYLE_ERROR;
|
344 |
+
}
|
345 |
+
|
346 |
+
state.tokenize = parseProcessingInstructionBody;
|
347 |
+
return STYLE_INSTRUCTION;
|
348 |
+
}
|
349 |
+
|
350 |
+
function parseProcessingInstructionBody(stream, state) {
|
351 |
+
stream.eatWhile(/[^?]/);
|
352 |
+
if(stream.eat("?")) {
|
353 |
+
if(stream.eat(">")) {
|
354 |
+
popContext(state);
|
355 |
+
state.tokenize = state.context == null ? parseDocument : parseElementBlock;
|
356 |
+
}
|
357 |
+
}
|
358 |
+
return STYLE_INSTRUCTION;
|
359 |
+
}
|
360 |
+
|
361 |
+
|
362 |
+
///////////////////////////////////////////////////////////////////////////
|
363 |
+
// context: XML declaration
|
364 |
+
//
|
365 |
+
// XML declaration is of the following format:
|
366 |
+
// <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
367 |
+
// - must start at the first character of the first line
|
368 |
+
// - may span multiple lines
|
369 |
+
// - must include 'version'
|
370 |
+
// - may include 'encoding' and 'standalone' (in that order after 'version')
|
371 |
+
// - attribute names must be lowercase
|
372 |
+
// - cannot contain anything else on the line
|
373 |
+
function parseDeclarationVersion(stream, state) {
|
374 |
+
state.tokenize = parseDeclarationEncoding;
|
375 |
+
|
376 |
+
if(isTokenSeparated(stream) && stream.match(/^version( )*=( )*"([a-zA-Z0-9_.:]|\-)+"/)) {
|
377 |
+
return STYLE_INSTRUCTION;
|
378 |
+
}
|
379 |
+
stream.skipToEnd();
|
380 |
+
return STYLE_ERROR;
|
381 |
+
}
|
382 |
+
|
383 |
+
function parseDeclarationEncoding(stream, state) {
|
384 |
+
state.tokenize = parseDeclarationStandalone;
|
385 |
+
|
386 |
+
if(isTokenSeparated(stream) && stream.match(/^encoding( )*=( )*"[A-Za-z]([A-Za-z0-9._]|\-)*"/)) {
|
387 |
+
return STYLE_INSTRUCTION;
|
388 |
+
}
|
389 |
+
return null;
|
390 |
+
}
|
391 |
+
|
392 |
+
function parseDeclarationStandalone(stream, state) {
|
393 |
+
state.tokenize = parseDeclarationEndTag;
|
394 |
+
|
395 |
+
if(isTokenSeparated(stream) && stream.match(/^standalone( )*=( )*"(yes|no)"/)) {
|
396 |
+
return STYLE_INSTRUCTION;
|
397 |
+
}
|
398 |
+
return null;
|
399 |
+
}
|
400 |
+
|
401 |
+
function parseDeclarationEndTag(stream, state) {
|
402 |
+
state.tokenize = parseDocument;
|
403 |
+
|
404 |
+
if(stream.match("?>") && stream.eol()) {
|
405 |
+
popContext(state);
|
406 |
+
return STYLE_INSTRUCTION;
|
407 |
+
}
|
408 |
+
stream.skipToEnd();
|
409 |
+
return STYLE_ERROR;
|
410 |
+
}
|
411 |
+
|
412 |
+
///////////////////////////////////////////////////////////////////////////
|
413 |
+
// returned object
|
414 |
+
return {
|
415 |
+
electricChars: "/",
|
416 |
+
|
417 |
+
startState: function() {
|
418 |
+
return {
|
419 |
+
tokenize: parseDocument,
|
420 |
+
tokParams: {},
|
421 |
+
lineNumber: 0,
|
422 |
+
lineError: false,
|
423 |
+
context: null,
|
424 |
+
indented: 0
|
425 |
+
};
|
426 |
+
},
|
427 |
+
|
428 |
+
token: function(stream, state) {
|
429 |
+
if(stream.sol()) {
|
430 |
+
// initialize a new line
|
431 |
+
state.lineNumber++;
|
432 |
+
state.lineError = false;
|
433 |
+
state.indented = stream.indentation();
|
434 |
+
}
|
435 |
+
|
436 |
+
// eat all (the spaces) you can
|
437 |
+
if(stream.eatSpace()) return null;
|
438 |
+
|
439 |
+
// run the current tokenize function, according to the state
|
440 |
+
var style = state.tokenize(stream, state);
|
441 |
+
|
442 |
+
// is there an error somewhere in the line?
|
443 |
+
state.lineError = (state.lineError || style == "error");
|
444 |
+
|
445 |
+
return style;
|
446 |
+
},
|
447 |
+
|
448 |
+
blankLine: function(state) {
|
449 |
+
// blank lines are lines too!
|
450 |
+
state.lineNumber++;
|
451 |
+
state.lineError = false;
|
452 |
+
},
|
453 |
+
|
454 |
+
indent: function(state, textAfter) {
|
455 |
+
if(state.context) {
|
456 |
+
if(state.context.noIndent == true) {
|
457 |
+
// do not indent - no return value at all
|
458 |
+
return;
|
459 |
+
}
|
460 |
+
if(textAfter.match(/^<\/.*/)) {
|
461 |
+
// eng-tag - indent back to last context
|
462 |
+
return state.context.indent;
|
463 |
+
}
|
464 |
+
// indent to last context + regular indent unit
|
465 |
+
return state.context.indent + indentUnit;
|
466 |
+
}
|
467 |
+
return 0;
|
468 |
+
},
|
469 |
+
|
470 |
+
compareStates: function(a, b) {
|
471 |
+
if (a.indented != b.indented) return false;
|
472 |
+
for (var ca = a.context, cb = b.context; ; ca = ca.prev, cb = cb.prev) {
|
473 |
+
if (!ca || !cb) return ca == cb;
|
474 |
+
if (ca.tagName != cb.tagName) return false;
|
475 |
+
}
|
476 |
+
}
|
477 |
+
};
|
478 |
+
});
|
479 |
+
|
480 |
+
CodeMirror.defineMIME("application/xml", "purexml");
|
481 |
+
CodeMirror.defineMIME("text/xml", "purexml");
|
tinymce-plugins/cmseditor/js/theme/default.css
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.cm-s-default span.cm-keyword {color: #708;}
|
2 |
+
.cm-s-default span.cm-atom {color: #219;}
|
3 |
+
.cm-s-default span.cm-number {color: #164;}
|
4 |
+
.cm-s-default span.cm-def {color: #00f;}
|
5 |
+
.cm-s-default span.cm-variable {color: black;}
|
6 |
+
.cm-s-default span.cm-variable-2 {color: #05a;}
|
7 |
+
.cm-s-default span.cm-variable-3 {color: #0a5;}
|
8 |
+
.cm-s-default span.cm-property {color: black;}
|
9 |
+
.cm-s-default span.cm-operator {color: black;}
|
10 |
+
.cm-s-default span.cm-comment {color: #a50;}
|
11 |
+
.cm-s-default span.cm-string {color: #a11;}
|
12 |
+
.cm-s-default span.cm-string-2 {color: #f50;}
|
13 |
+
.cm-s-default span.cm-meta {color: #555;}
|
14 |
+
.cm-s-default span.cm-error {color: #f00;}
|
15 |
+
.cm-s-default span.cm-qualifier {color: #555;}
|
16 |
+
.cm-s-default span.cm-builtin {color: #30a;}
|
17 |
+
.cm-s-default span.cm-bracket {color: #cc7;}
|
18 |
+
.cm-s-default span.cm-tag {color: #170;}
|
19 |
+
.cm-s-default span.cm-attribute {color: #00c;}
|
tinymce-plugins/cmseditor/js/theme/elegant.css
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.cm-s-elegant span.cm-number, .cm-s-elegant span.cm-string, .cm-s-elegant span.cm-atom {color: #762;}
|
2 |
+
.cm-s-elegant span.cm-comment {color: #262;font-style: italic;}
|
3 |
+
.cm-s-elegant span.cm-meta {color: #555;font-style: italic;}
|
4 |
+
.cm-s-elegant span.cm-variable {color: black;}
|
5 |
+
.cm-s-elegant span.cm-variable-2 {color: #b11;}
|
6 |
+
.cm-s-elegant span.cm-qualifier {color: #555;}
|
7 |
+
.cm-s-elegant span.cm-keyword {color: #730;}
|
8 |
+
.cm-s-elegant span.cm-builtin {color: #30a;}
|
9 |
+
.cm-s-elegant span.cm-error {background-color: #fdd;}
|
tinymce-plugins/cmseditor/js/theme/neat.css
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.cm-s-neat span.cm-comment { color: #a86; }
|
2 |
+
.cm-s-neat span.cm-keyword { font-weight: bold; color: blue; }
|
3 |
+
.cm-s-neat span.cm-string { color: #a22; }
|
4 |
+
.cm-s-neat span.cm-builtin { font-weight: bold; color: #077; }
|
5 |
+
.cm-s-neat span.cm-special { font-weight: bold; color: #0aa; }
|
6 |
+
.cm-s-neat span.cm-variable { color: black; }
|
7 |
+
.cm-s-neat span.cm-number, .cm-s-neat span.cm-atom { color: #3a3; }
|
8 |
+
.cm-s-neat span.cm-meta {color: #555;}
|
tinymce-plugins/cmseditor/js/theme/night.css
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* Loosely based on the Midnight Textmate theme */
|
2 |
+
|
3 |
+
.cm-s-night { background: #0a001f; color: #f8f8f8; }
|
4 |
+
.cm-s-night span.CodeMirror-selected { background: #a8f !important; }
|
5 |
+
.cm-s-night .CodeMirror-gutter { background: #0a001f; border-right: 1px solid #aaa; }
|
6 |
+
.cm-s-night .CodeMirror-gutter-text { color: #f8f8f8; }
|
7 |
+
.cm-s-night .CodeMirror-cursor { border-left: 1px solid white !important; }
|
8 |
+
|
9 |
+
.cm-s-night span.cm-comment { color: #6900a1; }
|
10 |
+
.cm-s-night span.cm-atom { color: #845dc4; }
|
11 |
+
.cm-s-night span.cm-number, .cm-s-night span.cm-attribute { color: #ffd500; }
|
12 |
+
.cm-s-night span.cm-keyword { color: #599eff; }
|
13 |
+
.cm-s-night span.cm-string { color: #37f14a; }
|
14 |
+
.cm-s-night span.cm-meta { color: #7678e2; }
|
15 |
+
.cm-s-night span.cm-variable-2, .cm-s-night span.cm-tag { color: #99b2ff; }
|
16 |
+
.cm-s-night span.cm-variable-3, .cm-s-night span.cm-def { color: white; }
|
17 |
+
.cm-s-night span.cm-error { color: #9d1e15; }
|
18 |
+
.cm-s-night span.cm-bracket { color: #8da6ce; }
|
19 |
+
.cm-s-night span.cm-comment { color: #6900a1; }
|
20 |
+
.cm-s-night span.cm-builtin, .cm-s-night span.cm-special { color: #ff9e59; }
|
tinymce-plugins/cmseditor/langs/en.js
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
tinyMCE.addI18n('en.example',{
|
2 |
+
desc : 'This is just a template button'
|
3 |
+
});
|
tinymce-plugins/cmseditor/langs/en_dlg.js
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
tinyMCE.addI18n('en.example_dlg',{
|
2 |
+
title : 'This is just a example title'
|
3 |
+
});
|
wpbe-options.php
CHANGED
@@ -1,87 +1,55 @@
|
|
1 |
<div class="wrap">
|
2 |
-
<h2><?php _e('Email
|
3 |
|
4 |
<form method="post" action="options.php" id="wpbe_options_form">
|
5 |
<?php settings_fields('wpbe_full_options'); ?>
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
<
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
<
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
<th role="row"><?php _e('Template variables', 'wp-better-emails'); ?></th>
|
30 |
-
<td>
|
31 |
-
<p><?php _e('Some dynamic tags can be included in your email template :', 'wp-better-emails'); ?></p>
|
32 |
-
<ul>
|
33 |
-
<li><?php _e('<strong>%content%</strong> : will be replaced by the message content.', 'wp-better-emails'); ?><br />
|
34 |
-
<span class="description"><?php _e('NOTE: The content tag is <strong>required</strong>, WP Better Emails will be automatically desactivated if no content tag is found.', 'wp-better-emails'); ?></span></li>
|
35 |
-
<li><?php _e('<strong>%blog_url%</strong> : will be replaced by your blog URL.', 'wp-better-emails'); ?></li>
|
36 |
-
<li><?php _e('<strong>%blog_name%</strong> : will be replaced by your blog name.', 'wp-better-emails'); ?></li>
|
37 |
-
<li><?php _e('<strong>%blog_description%</strong> : will be replaced by your blog description.', 'wp-better-emails'); ?></li>
|
38 |
-
<li><?php _e('<strong>%admin_email%</strong> : will be replaced by admin email.', 'wp-better-emails'); ?></li>
|
39 |
-
<li><?php _e('<strong>%date%</strong> : will be replaced by current date, as formatted in <a href="options-general.php">general options</a>.', 'wp-better-emails'); ?></li>
|
40 |
-
<li><?php _e('<strong>%time%</strong> : will be replaced by current time, as formatted in <a href="options-general.php">general options</a>.', 'wp-better-emails'); ?></li>
|
41 |
-
</ul>
|
42 |
-
</td>
|
43 |
-
</tr>
|
44 |
-
<tr valign="top">
|
45 |
-
<th scope="row">
|
46 |
-
<label for="wpbe_template"><?php _e('HTML Template', 'wp-better-emails'); ?></label>
|
47 |
-
</th>
|
48 |
-
<td>
|
49 |
-
<textarea id="wpbe_template" name="wpbe_options[template]" cols="80" rows="20"><?php echo $options['template']; ?></textarea>
|
50 |
-
<p>
|
51 |
-
<label for="wpbe_preview_email"><?php _e('Send an email preview to', 'wp-better-emails'); ?></label>
|
52 |
-
<input type="hidden" id="wpbe_nonce_preview" name="_ajax_nonce" value="<?php echo wp_create_nonce( 'email_preview' ); ?>" />
|
53 |
-
<input type="text" id="wpbe_preview_email" name="wpbe_preview_email" value="<?php echo get_option('admin_email'); ?>" />
|
54 |
-
<a href="javascript:void(0);" class="button" id="wpbe_send_preview"><?php _e('Send', 'wp-better-emails'); ?></a><span id="loading"></span>
|
55 |
-
<img src="<?php echo get_option('siteurl'); ?>/wp-admin/images/wpspin_light.gif" id="ajax-loading" style="visibility: hidden;" alt="Loading" />
|
56 |
-
<br /><span class="description"><?php __('You must save your template before sending an email preview.', 'wp-better-emails'); ?></span>
|
57 |
-
<span id="wpbe_preview_message"></span>
|
58 |
-
</p>
|
59 |
-
</td>
|
60 |
-
</tr>
|
61 |
-
</table>
|
62 |
-
</div>
|
63 |
-
<div id="tab3" class="wpbe_tab_content">
|
64 |
-
<h3><?php _e('Designing & coding email templates', 'wp-better-emails'); ?></h3>
|
65 |
-
<p><?php _e('Here are a few ressources about email formatting :', 'wp-better-emails') ?></p>
|
66 |
-
<ul>
|
67 |
-
<li><a href="http://www.campaignmonitor.com/resources/" target="_blank">http://www.campaignmonitor.com/resources/</a></li>
|
68 |
-
<li><a href="http://articles.sitepoint.com/article/code-html-email-newsletters/" target="_blank">http://articles.sitepoint.com/article/code-html-email-newsletters/</a></li>
|
69 |
-
</ul>
|
70 |
-
<h3><?php _e('Converting HTML templates', 'wp-better-emails'); ?></h3>
|
71 |
-
<p><?php _e('Coding HTML for emails requires CSS styles to be inline. Here\'s a tool powered by MailChimp that will convert your styles placed in the <code><head></code> tag to inline : ', 'wp-better-emails'); ?></p>
|
72 |
-
<ul>
|
73 |
-
<li><?php _e('<a href="http://www.mailchimp.com/labs/inlinecss.php" target="_blank">http://www.mailchimp.com/labs/inlinecss.php</a>', 'wp-better-emails'); ?></li>
|
74 |
-
</ul>
|
75 |
-
<h3><?php _e('Requests & Bug report', 'wp-better-emails'); ?></h3>
|
76 |
-
<p><?php _e('If you have any idea to improve this plugin or any bug to report, please email me at : <a href="mailto:plugins@artyshow-studio.fr?subject=[wp-better-emails]">plugins@artyshow-studio.fr</a>', 'wp-better-emails'); ?></p>
|
77 |
-
<h3><?php _e('Credits', 'wp-better-emails'); ?></h3>
|
78 |
-
<ul>
|
79 |
-
<li><?php _e('MarkItUp! : jQuery HTML editor <a href="http://markitup.jaysalvat.com/home/" target="_blank">http://markitup.jaysalvat.com/home/</a>', 'wp-better-emails'); ?></li>
|
80 |
-
</ul>
|
81 |
-
</div>
|
82 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
<p class="submit">
|
84 |
<input type="submit" class="button-primary" value="<?php _e('Save Changes', 'wp-better-emails') ?>" />
|
85 |
</p>
|
86 |
</form>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
</div>
|
1 |
<div class="wrap">
|
2 |
+
<h2><?php _e('Email settings', 'wp-better-emails'); ?></h2>
|
3 |
|
4 |
<form method="post" action="options.php" id="wpbe_options_form">
|
5 |
<?php settings_fields('wpbe_full_options'); ?>
|
6 |
+
|
7 |
+
<!-- Sender options -->
|
8 |
+
<p style="margin-bottom: 0;"><?php _e('Set your own sender name and email address. Default Wordpress values will be used if empty.', 'wp-better-emails'); ?></p>
|
9 |
+
<table class="form-table">
|
10 |
+
<tr valign="top">
|
11 |
+
<th scope="row"><label for="wpbe_from_name"><?php _e('Name', 'wp-better-emails'); ?></label></th>
|
12 |
+
<td><input type="text" id="wpbe_from_name" class="regular-text" name="wpbe_options[from_name]" value="<?php esc_attr_e($this->options['from_name']); ?>" /></td>
|
13 |
+
</tr>
|
14 |
+
<tr valign="top">
|
15 |
+
<th scope="row"><label for="wpbe_from_email"><?php _e('Email address', 'wp-better-emails'); ?></label></th>
|
16 |
+
<td><input type="text" id="wpbe_from_email" class="regular-text" name="wpbe_options[from_email]" value="<?php echo esc_attr_e($this->options['from_email']); ?>" /></td>
|
17 |
+
</tr>
|
18 |
+
</table>
|
19 |
+
|
20 |
+
<!-- Template -->
|
21 |
+
<h3 class="wpbe_title"><?php _e('HTML Template', 'wp-better-emails'); ?>
|
22 |
+
<?php if( version_compare($wp_version, '3.1', '>') ): ?>
|
23 |
+
<a class="thickbox button" title="<?php esc_attr_e('Live template preview', 'wp-better-emails'); ?>" id="wpbe_preview_template" href="<?php echo plugins_url('preview.html?keepThis=true&TB_iframe=true&height=400&width=700', __FILE__); ?>"><?php _e('Live preview', 'wp-better-emails'); ?></a>
|
24 |
+
<?php endif; ?>
|
25 |
+
</h3>
|
26 |
+
<p><?php _e('Edit the HTML email template if you want to customize it. You might have a look at the <a href="#" id="wpbe_help">help tab</a> for further information.', 'wp-better-emails'); ?></p>
|
27 |
+
<div id="wpbe_template_container">
|
28 |
+
<?php $this->template_editor() ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
</div>
|
30 |
+
<div id="wpbe_preview_message"></div>
|
31 |
+
<table class="form-table">
|
32 |
+
<tr valign="top">
|
33 |
+
<th scope="row">
|
34 |
+
<label for="wpbe_email_preview_field"><?php _e('Send an email preview to', 'wp-better-emails'); ?></label>
|
35 |
+
</th>
|
36 |
+
<td>
|
37 |
+
<input type="text" id="wpbe_email_preview_field" name="wpbe_preview_email" class="regular-text" value="<?php esc_attr_e(get_option('admin_email')); ?>" />
|
38 |
+
<a href="javascript:void(0);" class="button" id="wpbe_send_preview"><?php _e('Send', 'wp-better-emails'); ?></a><span id="wpbe_loading"></span>
|
39 |
+
<img src="<?php echo admin_url('images/wpspin_light.gif'); ?>" id="wpbe_ajax_loading" style="visibility: hidden;" alt="Loading" />
|
40 |
+
<br /><span class="description"><?php _e('You must save your template before sending an email preview.', 'wp-better-emails'); ?></span>
|
41 |
+
</td>
|
42 |
+
</tr>
|
43 |
+
</table>
|
44 |
<p class="submit">
|
45 |
<input type="submit" class="button-primary" value="<?php _e('Save Changes', 'wp-better-emails') ?>" />
|
46 |
</p>
|
47 |
</form>
|
48 |
+
<!-- Support -->
|
49 |
+
<div id="wpbe_support">
|
50 |
+
<h3><?php _e('Support & bug report', 'wp-better-emails'); ?></h3>
|
51 |
+
<p><?php _e('If you have any idea to improve this plugin or any bug to report, please email me at : <a href="mailto:plugins@artyshow-studio.fr?subject=[wp-better-emails]">plugins@artyshow-studio.fr</a>', 'wp-better-emails'); ?></p>
|
52 |
+
<?php $donation_link = 'https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=7Q49VJQNRCQ8E&lc=FR&item_name=ArtyShow&item_number=wp%2dbetter%2demails¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted'; ?>
|
53 |
+
<p><?php printf(__('You like this plugin ? You use it in a business context ? Please, consider a <a href="%s" target="_blank" rel="external">donation</a>.', 'wp-better-emails'), $donation_link ); ?></p>
|
54 |
+
</div>
|
55 |
</div>
|
wpbe.php
CHANGED
@@ -1,334 +1,528 @@
|
|
1 |
<?php
|
2 |
/*
|
3 |
-
Plugin Name: WP Better Emails
|
4 |
-
Plugin URI: http://wordpress.org/extend/plugins/wp-better-emails/
|
5 |
-
Description: Beautify the default text/plain WP mails into fully customizable HTML emails.
|
6 |
-
Version: 0.
|
7 |
-
Author: ArtyShow
|
8 |
-
Author URI: http://wordpress.org/extend/plugins/wp-better-emails/
|
9 |
-
|
10 |
-
|
11 |
-
/**
|
12 |
-
* Hooks & actions
|
13 |
*/
|
14 |
-
register_activation_hook(__FILE__,'wpbe_register_options');
|
15 |
-
add_action('init', 'wpbe_init_textdomain');
|
16 |
-
add_action('admin_init', 'wpbe_plugin_init');
|
17 |
-
add_action('admin_menu', 'wpbe_add_settings_page');
|
18 |
-
add_action('wp_ajax_send_preview', 'wpbe_ajax_send_preview');
|
19 |
-
add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'wpbe_add_settings_link');
|
20 |
-
add_filter('wp_mail_from_name', 'wpbe_set_from_name');
|
21 |
-
add_filter('wp_mail_from', 'wpbe_set_from_email');
|
22 |
-
add_filter('wp_mail_content_type', 'wpbe_set_content_type');
|
23 |
-
|
24 |
-
/**
|
25 |
-
* Load the text domain for i18n
|
26 |
-
*
|
27 |
-
* @since 0.1.1
|
28 |
-
*/
|
29 |
-
function wpbe_init_textdomain() {
|
30 |
-
load_plugin_textdomain( 'wp-better-emails', null, basename(dirname(__FILE__)) . '/langs/' );
|
31 |
-
}
|
32 |
|
33 |
-
|
34 |
-
|
35 |
-
*
|
36 |
-
* @since 0.1
|
37 |
-
*/
|
38 |
-
function wpbe_plugin_init() {
|
39 |
-
register_setting('wpbe_full_options', 'wpbe_options', 'wpbe_options_validate');
|
40 |
-
wp_register_script('wpbe-admin-script', plugins_url('js/wpbe-admin-script.js', __FILE__), array('jquery'), null, true);
|
41 |
-
wp_register_script('jquery-cookie', plugins_url('js/jquery.cookie.js', __FILE__), array('jquery'), null, true);
|
42 |
-
wp_register_script('jquery-markitup', plugins_url('markitup/jquery.markitup.js', __FILE__), array('jquery'), null, true);
|
43 |
-
wp_register_script('markitup-set', plugins_url('markitup/sets/html/set.js', __FILE__), array('jquery'), null, true);
|
44 |
-
wp_register_style('wpbe-admin-style', plugins_url('css/wpbe-admin-style.css', __FILE__));
|
45 |
-
wp_register_style('markitup-skin', plugins_url('markitup/skins/simple/style.css', __FILE__));
|
46 |
-
wp_register_style('markitup-skin-toolbar', plugins_url('markitup/sets/html/style.css', __FILE__));
|
47 |
-
}
|
48 |
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
$links[] = '<a href="options-general.php?page=wpbe_options">' . __('Settings', 'wp-better-emails') . '</a>';
|
59 |
-
return $links;
|
60 |
-
}
|
61 |
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
* @since 0.1
|
66 |
*/
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
}
|
75 |
-
die(__('WP Better Emails requires WordPress 2.8 or newer.', 'wp-better-emails'));
|
76 |
-
}
|
77 |
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
}
|
93 |
-
}
|
94 |
|
95 |
-
|
96 |
-
|
97 |
-
*/
|
98 |
-
$wpbe_options = get_option('wpbe_options');
|
99 |
|
100 |
-
|
101 |
-
|
102 |
-
*
|
103 |
-
* @since 0.1
|
104 |
-
*/
|
105 |
-
function wpbe_add_settings_page() {
|
106 |
-
$page = add_options_page(__('Email Options', 'wp-better-emails'), __('Email Options', 'wp-better-emails'), 'administrator', 'wpbe_options', 'wpbe_options_page');
|
107 |
-
add_action('admin_print_scripts-' . $page, 'wpbe_admin_print_script');
|
108 |
-
add_action('admin_print_styles-' . $page, 'wpbe_admin_print_style');
|
109 |
-
}
|
110 |
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
|
|
125 |
|
126 |
-
/**
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
function
|
132 |
-
|
133 |
-
|
134 |
-
wp_enqueue_style('markitup-skin');
|
135 |
-
wp_enqueue_style('markitup-skin-toolbar');
|
136 |
-
}
|
137 |
|
138 |
-
/**
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
function
|
144 |
-
|
145 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
146 |
|
147 |
-
/**
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
|
|
|
|
155 |
|
156 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
157 |
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
165 |
|
166 |
-
|
167 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
|
176 |
-
|
177 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
|
179 |
-
/**
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
if( empty($preview_email) )
|
189 |
-
die( '<div class="error"><p>' . __('Please enter an email', 'wp-better-emails') . '</p></div>' );
|
190 |
-
if( !is_email($preview_email) )
|
191 |
-
die( '<div class="error"><p>' . __('Please enter a valid email', 'wp-better-emails') . '</p></div>' );
|
192 |
-
$message = __('Hey !', 'wp-better-emails');
|
193 |
-
$message .= "\r\n\r\n";
|
194 |
-
$message .= __('This is a sample email to test your template.', 'wp-better-emails');
|
195 |
-
$message .= "\r\n\r\n";
|
196 |
-
$message .= __('If you\'re not skilled in HTML/CSS email coding, I strongly recommend to leave the default template as it is. It has been tested on various and popular email clients like Gmail, Yahoo Mail, Hotmail/Live, Thunderbird, Apple Mail, Outlook, and many more. ', 'wp-better-emails');
|
197 |
-
$message .= "\r\n\r\n";
|
198 |
-
$message .= __('If you have any problem or any suggestions to improve this plugin, please let me know.', 'wp-better-emails');
|
199 |
-
$message .= "\r\n\r\n";
|
200 |
-
if( wp_mail( $preview_email, '[' . wp_specialchars_decode(get_option('blogname'), ENT_QUOTES) . '] - ' . __('Email template preview', 'wp-better-emails'), $message) )
|
201 |
-
die('<div class="updated"><p>' . __('An email preview has been successfully sent to ' . $preview_email, 'wp-better-emails') . '</p></div>');
|
202 |
-
else
|
203 |
-
die( '<div class="error"><p>' . __('An error occured while sending email. Please check your server configuration.', 'wp-better-emails') . '</p></div>' );
|
204 |
-
}
|
205 |
|
206 |
-
/**
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
global $wpbe_options;
|
217 |
-
$template = '';
|
218 |
-
if( isset ($wpbe_options['template']) && !empty($wpbe_options['template']) )
|
219 |
-
$template .= $wpbe_options['template'];
|
220 |
-
$html_email = str_replace('%content%', $body, $template);
|
221 |
-
return $html_email;
|
222 |
-
}
|
223 |
|
224 |
-
/**
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
function
|
232 |
-
$to_replace = array(
|
233 |
-
'blog_url' => get_option('siteurl'),
|
234 |
-
'blog_name' => get_option('blogname'),
|
235 |
-
'blog_description' => get_option('blogdescription'),
|
236 |
-
'admin_email' => get_option('admin_email'),
|
237 |
-
'date' => date_i18n( get_option('date_format') ),
|
238 |
-
'time' => date_i18n( get_option('time_format') )
|
239 |
-
);
|
240 |
-
foreach ( $to_replace as $tag => $var ) {
|
241 |
-
$template = str_replace('%' . $tag . '%', $var, $template);
|
242 |
-
}
|
243 |
-
return $template;
|
244 |
-
}
|
245 |
|
246 |
-
|
247 |
-
* Checks the WP Better Emails options to activate the new mail function
|
248 |
-
*
|
249 |
-
* @since 0.1
|
250 |
-
* @return bool
|
251 |
-
*/
|
252 |
-
function wpbe_check_template() {
|
253 |
-
global $wpbe_options;
|
254 |
-
if ( strpos( $wpbe_options['template'], '%content%') === false || empty($wpbe_options['template']) )
|
255 |
-
return false;
|
256 |
-
return true;
|
257 |
-
}
|
258 |
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
*/
|
267 |
-
function wpbe_set_from_email( $from_email ) {
|
268 |
-
global $wpbe_options;
|
269 |
-
if ( !empty($wpbe_options['from_email']) && is_email( $wpbe_options['from_email'] ) )
|
270 |
-
return $wpbe_options['from_email'];
|
271 |
-
return $from_email;
|
272 |
-
}
|
273 |
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
288 |
|
289 |
-
/**
|
290 |
-
* Always set content type to HTML
|
291 |
-
*
|
292 |
-
* @since 0.1
|
293 |
-
* @param string $content_type
|
294 |
-
* @return string $content_type
|
295 |
-
*/
|
296 |
-
function wpbe_set_content_type( $content_type ) {
|
297 |
-
// Only convert if the message is text/plain and the template is ok
|
298 |
-
if( $content_type == 'text/plain' && wpbe_check_template() === true ) {
|
299 |
-
add_action('phpmailer_init', 'wpbe_send_html');
|
300 |
-
return $content_type = 'text/html';
|
301 |
}
|
302 |
-
return $content_type;
|
303 |
-
}
|
304 |
|
305 |
-
/**
|
306 |
-
* Add the email template and set it multipart
|
307 |
-
*
|
308 |
-
* @since 0.1
|
309 |
-
* @param object $phpmailer
|
310 |
-
*/
|
311 |
-
function wpbe_send_html( $phpmailer ) {
|
312 |
-
// Set the original plain text message
|
313 |
-
$phpmailer->AltBody = wp_specialchars_decode($phpmailer->Body, ENT_QUOTES);
|
314 |
-
// Clean < and > around text links in WP 3.1
|
315 |
-
$phpmailer->Body = wpbe_esc_textlinks($phpmailer->Body);
|
316 |
-
// Convert line breaks & make links clickable
|
317 |
-
$phpmailer->Body = nl2br ( make_clickable ($phpmailer->Body) );
|
318 |
-
// Add template to message
|
319 |
-
$phpmailer->Body = wpbe_email_templatize($phpmailer->Body);
|
320 |
-
// Replace variables in email
|
321 |
-
$phpmailer->Body = wpbe_template_replacement($phpmailer->Body);
|
322 |
}
|
323 |
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
* @since 0.1.2
|
328 |
-
* @param string $body
|
329 |
-
* @return string
|
330 |
-
*/
|
331 |
-
function wpbe_esc_textlinks( $body ) {
|
332 |
-
return preg_replace('#<(https?://[^*]+)>#', '$1', $body);
|
333 |
}
|
334 |
?>
|
1 |
<?php
|
2 |
/*
|
3 |
+
Plugin Name: WP Better Emails
|
4 |
+
Plugin URI: http://wordpress.org/extend/plugins/wp-better-emails/
|
5 |
+
Description: Beautify the default text/plain WP mails into fully customizable HTML emails.
|
6 |
+
Version: 0.2
|
7 |
+
Author: ArtyShow
|
8 |
+
Author URI: http://wordpress.org/extend/plugins/wp-better-emails/
|
9 |
+
License: GPLv2
|
|
|
|
|
|
|
10 |
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
|
12 |
+
/*
|
13 |
+
Copyright (c) 2011 Nicolas Lemoine.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
+
This program is free software; you can redistribute it and/or
|
16 |
+
modify it under the terms of the GNU General Public License
|
17 |
+
as published by the Free Software Foundation; either version 2
|
18 |
+
of the License, or (at your option) any later version.
|
19 |
+
|
20 |
+
This program is distributed in the hope that it will be useful,
|
21 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
22 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
23 |
+
GNU General Public License for more details.
|
|
|
|
|
|
|
24 |
|
25 |
+
You should have received a copy of the GNU General Public License
|
26 |
+
along with this program; if not, write to the Free Software
|
27 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
28 |
*/
|
29 |
+
|
30 |
+
if (!class_exists('WP_Better_Emails')) {
|
31 |
+
|
32 |
+
if (!defined('WPBE_JS_URL'))
|
33 |
+
define('WPBE_JS_URL', plugin_dir_url(__FILE__) . 'js');
|
34 |
+
if (!defined('WPBE_CSS_URL'))
|
35 |
+
define('WPBE_CSS_URL', plugin_dir_url(__FILE__) . 'css');
|
36 |
+
|
37 |
+
class WP_Better_Emails {
|
38 |
+
|
39 |
+
var $options = array();
|
40 |
+
var $page = '';
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Construct function (old way)
|
44 |
+
*
|
45 |
+
* @since 0.2
|
46 |
+
*/
|
47 |
+
function WP_Better_Emails() {
|
48 |
+
$this->__construct();
|
49 |
}
|
|
|
|
|
50 |
|
51 |
+
/**
|
52 |
+
* Construct function
|
53 |
+
*
|
54 |
+
* @since 0.2
|
55 |
+
*/
|
56 |
+
function __construct() {
|
57 |
+
global $wp_version;
|
58 |
+
|
59 |
+
$this->get_options();
|
60 |
+
|
61 |
+
// Front end filter
|
62 |
+
add_filter('wp_mail_from_name', array(&$this, 'set_from_name'));
|
63 |
+
add_filter('wp_mail_from', array($this, 'set_from_email'));
|
64 |
+
add_filter('wp_mail_content_type', array(&$this, 'set_content_type'));
|
|
|
|
|
65 |
|
66 |
+
if (!is_admin())
|
67 |
+
return;
|
|
|
|
|
68 |
|
69 |
+
// Load translations
|
70 |
+
load_plugin_textdomain('wp-better-emails', null, basename(dirname(__FILE__)) . '/langs/');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
|
72 |
+
// Actions
|
73 |
+
add_action('admin_init', array(&$this, 'init'));
|
74 |
+
add_action('admin_menu', array(&$this, 'admin_menu'));
|
75 |
+
add_action('wp_ajax_send_preview', array(&$this, 'ajax_send_preview'));
|
76 |
+
add_action("admin_head", array(&$this, 'load_wp_tiny_mce'));
|
77 |
+
if( version_compare($wp_version, '3.2', '<') && version_compare($wp_version, '3.0', '>') )
|
78 |
+
add_action( 'admin_print_footer_scripts', 'wp_tiny_mce_preload_dialogs');
|
79 |
+
|
80 |
+
// Filters
|
81 |
+
add_filter('plugin_action_links_' . plugin_basename(__FILE__), array(&$this, 'settings_link'));
|
82 |
+
add_filter('contextual_help', array(&$this, 'contextual_help'), 10, 3);
|
83 |
+
add_filter('mce_external_plugins', array(&$this, 'tinymce_plugins'));
|
84 |
+
add_filter('mce_buttons', array(&$this, 'tinymce_buttons'));
|
85 |
+
add_filter('tiny_mce_before_init', array(&$this, 'tinymce_config'));
|
86 |
+
}
|
87 |
|
88 |
+
/**
|
89 |
+
* Get recorded options
|
90 |
+
*
|
91 |
+
* @since 0.2
|
92 |
+
*/
|
93 |
+
function get_options() {
|
94 |
+
$this->options = get_option('wpbe_options');
|
95 |
+
}
|
|
|
|
|
|
|
96 |
|
97 |
+
/**
|
98 |
+
* Set the default options
|
99 |
+
*
|
100 |
+
* @since 0.2
|
101 |
+
*/
|
102 |
+
function set_options() {
|
103 |
+
$template = '';
|
104 |
+
@require('templates/template-1.php');
|
105 |
+
$this->options = array(
|
106 |
+
'from_email' => '',
|
107 |
+
'from_name' => '',
|
108 |
+
'template' => $template
|
109 |
+
);
|
110 |
+
if (get_option('wpbe_options') == null)
|
111 |
+
add_option('wpbe_options', $this->options);
|
112 |
+
}
|
113 |
|
114 |
+
/**
|
115 |
+
* Init plugin options to white list our options & register our script
|
116 |
+
*
|
117 |
+
* @since 0.1
|
118 |
+
*/
|
119 |
+
function init() {
|
120 |
+
register_setting('wpbe_full_options', 'wpbe_options', array(&$this, 'validate_options'));
|
121 |
+
wp_register_script('wpbe-admin-script', WPBE_JS_URL . '/wpbe-admin-script.js', array('jquery', 'thickbox'), null, true);
|
122 |
+
wp_register_style('wpbe-admin-style', WPBE_CSS_URL . '/wpbe-admin-style.css');
|
123 |
+
}
|
124 |
|
125 |
+
/**
|
126 |
+
* Settings link in the plugins page
|
127 |
+
*
|
128 |
+
* @since 0.1
|
129 |
+
*
|
130 |
+
* @param array $links Plugin links
|
131 |
+
* @return array Plugins links with settings added
|
132 |
+
*/
|
133 |
+
function settings_link($links) {
|
134 |
+
$links[] = '<a href="options-general.php?page=wpbe_options">' . __('Settings', 'wp-better-emails') . '</a>';
|
135 |
+
return $links;
|
136 |
+
}
|
137 |
|
138 |
+
/**
|
139 |
+
* Record options on plugin activation
|
140 |
+
*
|
141 |
+
* @since 0.1
|
142 |
+
* @global $wp_version
|
143 |
+
*/
|
144 |
+
function install() {
|
145 |
+
global $wp_version;
|
146 |
+
// Prevent activation if requirements are not met
|
147 |
+
// WP 2.8 required
|
148 |
+
if (version_compare($wp_version, '2.8', '<=')) {
|
149 |
+
deactivate_plugins(__FILE__);
|
150 |
+
wp_die(__('WP Better Emails requires WordPress 2.8 or newer.', 'wp-better-emails'), __('Upgrade your Wordpress installation.', 'wp-better-emails'));
|
151 |
+
}
|
152 |
+
$this->set_options();
|
153 |
+
}
|
154 |
|
155 |
+
/**
|
156 |
+
* Option page to the built-in settings menu
|
157 |
+
*
|
158 |
+
* @since 0.1
|
159 |
+
*/
|
160 |
+
function admin_menu() {
|
161 |
+
$this->page = add_options_page(__('Email settings', 'wp-better-emails'), __('WP Better Emails', 'wp-better-emails'), 'administrator', 'wpbe_options', array(&$this, 'admin_page'));
|
162 |
+
add_action('admin_print_scripts-' . $this->page, array(&$this, 'admin_print_script'));
|
163 |
+
add_action('admin_print_styles-' . $this->page, array(&$this, 'admin_print_style'));
|
164 |
+
}
|
165 |
|
166 |
+
/**
|
167 |
+
* Check if we're on the plugin page
|
168 |
+
*
|
169 |
+
* @since 0.2
|
170 |
+
* @global type $page_hook
|
171 |
+
* @return type
|
172 |
+
*/
|
173 |
+
function is_wpbe_page() {
|
174 |
+
global $page_hook;
|
175 |
+
if ($page_hook == $this->page)
|
176 |
+
return true;
|
177 |
+
return false;
|
178 |
+
}
|
179 |
|
180 |
+
/**
|
181 |
+
* Enqueue the script to display it on the options page
|
182 |
+
* Add Javascript to handle AJAX email preview
|
183 |
+
*
|
184 |
+
* @since 0.1
|
185 |
+
*/
|
186 |
+
function admin_print_script() {
|
187 |
+
wp_enqueue_script('wpbe-admin-script');
|
188 |
+
$protocol = isset($_SERVER["HTTPS"]) ? 'https://' : 'http://';
|
189 |
+
$ajax_vars = array(
|
190 |
+
'url' => admin_url('admin-ajax.php', $protocol),
|
191 |
+
'nonce' => wp_create_nonce('email_preview'),
|
192 |
+
'action' => 'send_preview'
|
193 |
+
);
|
194 |
+
wp_localize_script('wpbe-admin-script', 'wpbe_ajax_vars', $ajax_vars);
|
195 |
+
}
|
196 |
|
197 |
+
/**
|
198 |
+
* Enqueue the style to display it on the options page
|
199 |
+
*
|
200 |
+
* @since 0.1
|
201 |
+
*/
|
202 |
+
function admin_print_style() {
|
203 |
+
wp_enqueue_style('wpbe-admin-style');
|
204 |
+
wp_enqueue_style('thickbox');
|
205 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
206 |
|
207 |
+
/**
|
208 |
+
* Include admin options page
|
209 |
+
*
|
210 |
+
* @since 0.1
|
211 |
+
* @global $wp_version
|
212 |
+
*/
|
213 |
+
function admin_page() {
|
214 |
+
global $wp_version;
|
215 |
+
require('wpbe-options.php');
|
216 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
217 |
|
218 |
+
/**
|
219 |
+
* Sanitize each option value
|
220 |
+
*
|
221 |
+
* @since 0.1
|
222 |
+
* @param array $input The options returned by the options page
|
223 |
+
* @return array $input Sanitized values
|
224 |
+
*/
|
225 |
+
function validate_options($input) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
226 |
|
227 |
+
$from_email = strtolower($input['from_email']);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
228 |
|
229 |
+
// Checking emails
|
230 |
+
if (!empty($from_email) && !is_email($from_email)) {
|
231 |
+
add_settings_error('wpbe_options', 'settings_updated', __('Please enter a valid sender email address.', 'wp-better-emails'), 'error');
|
232 |
+
$input['from_email'] = '';
|
233 |
+
} else {
|
234 |
+
$input['from_email'] = sanitize_email($from_email);
|
235 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
236 |
|
237 |
+
// Check name
|
238 |
+
$input['from_name'] = esc_html($input['from_name']);
|
239 |
+
|
240 |
+
if (empty($input['template']))
|
241 |
+
add_settings_error('wpbe_options', 'settings_updated', __('Template is empty', 'wp-better-emails'));
|
242 |
+
// Check if %content% tag is the template body
|
243 |
+
elseif (strpos($input['template'], '%content%') === false)
|
244 |
+
add_settings_error('wpbe_options', 'settings_updated', __('No content tag found. The %content% tag is required in your template', 'wp-better-emails'));
|
245 |
+
$input['template'] = $input['template'];
|
246 |
+
|
247 |
+
return $input;
|
248 |
+
}
|
249 |
+
|
250 |
+
/**
|
251 |
+
* Send a email preview to test the template
|
252 |
+
*
|
253 |
+
* @since 0.1
|
254 |
+
* @param string $email
|
255 |
+
*/
|
256 |
+
function ajax_send_preview($email) {
|
257 |
+
if (!current_user_can('manage_options'))
|
258 |
+
die();
|
259 |
+
check_ajax_referer('email_preview');
|
260 |
+
$preview_email = sanitize_email($_POST['preview_email']);
|
261 |
+
if (empty($preview_email))
|
262 |
+
die('<div class="error"><p>' . __('Please enter an email', 'wp-better-emails') . '</p></div>');
|
263 |
+
if (!is_email($preview_email))
|
264 |
+
die('<div class="error"><p>' . __('Please enter a valid email', 'wp-better-emails') . '</p></div>');
|
265 |
+
$message = __('Hey !', 'wp-better-emails');
|
266 |
+
$message .= "\r\n\r\n";
|
267 |
+
$message .= __('This is a sample email to test your HTML template.', 'wp-better-emails');
|
268 |
+
$message .= "\r\n\r\n";
|
269 |
+
$message .= __('If you\'re not skilled in HTML/CSS email coding, I strongly recommend to leave the default template as it is. It has been tested on various and popular email clients like Gmail, Yahoo Mail, Hotmail/Live, Thunderbird, Apple Mail, Outlook, and many more.', 'wp-better-emails');
|
270 |
+
$message .= "\r\n\r\n";
|
271 |
+
$message .= __('If you have any problems or any suggestions to improve this plugin, please let me know.', 'wp-better-emails');
|
272 |
+
$message .= "\r\n\r\n";
|
273 |
+
if (wp_mail($preview_email, '[' . wp_specialchars_decode(get_option('blogname'), ENT_QUOTES) . '] - ' . __('Email template preview', 'wp-better-emails'), $message))
|
274 |
+
die('<div class="updated"><p>' . sprintf(__('An email preview has been successfully sent to %s' , 'wp-better-emails'), esc_attr($preview_email) ) . '</p></div>');
|
275 |
+
else
|
276 |
+
die('<div class="error"><p>' . __('An error occured while sending email. Please check your server configuration.', 'wp-better-emails') . '</p></div>');
|
277 |
+
}
|
278 |
+
|
279 |
+
/**
|
280 |
+
* Replace variables in the template
|
281 |
+
*
|
282 |
+
* @since 0.1
|
283 |
+
* @param string $template Template with variables
|
284 |
+
* @return string Template with variables replaced
|
285 |
+
*/
|
286 |
+
function template_vars_replacement($template) {
|
287 |
+
$to_replace = array(
|
288 |
+
'blog_url' => get_option('siteurl'),
|
289 |
+
'home_url' => get_option('home'),
|
290 |
+
'blog_name' => get_option('blogname'),
|
291 |
+
'blog_description' => get_option('blogdescription'),
|
292 |
+
'admin_email' => get_option('admin_email'),
|
293 |
+
'date' => date_i18n(get_option('date_format')),
|
294 |
+
'time' => date_i18n(get_option('time_format'))
|
295 |
+
);
|
296 |
+
$to_replace = apply_filters('wpbe_tags', $to_replace);
|
297 |
+
foreach ($to_replace as $tag => $var)
|
298 |
+
$template = str_replace('%' . $tag . '%', $var, $template);
|
299 |
+
return $template;
|
300 |
+
}
|
301 |
+
|
302 |
+
/**
|
303 |
+
* Checks the WP Better Emails options
|
304 |
+
*
|
305 |
+
* @since 0.1
|
306 |
+
* @return bool
|
307 |
+
*/
|
308 |
+
function check_template() {
|
309 |
+
if (strpos($this->options['template'], '%content%') === false || empty($this->options['template']))
|
310 |
+
return false;
|
311 |
+
return true;
|
312 |
+
}
|
313 |
+
|
314 |
+
/**
|
315 |
+
* Add the HTML template to the message body.
|
316 |
+
* Looks for %message% into the template and replace it with the message
|
317 |
+
*
|
318 |
+
* @since 0.1
|
319 |
+
* @param string $body The message to templatize
|
320 |
+
* @return string $email The email surrounded by template
|
321 |
+
*/
|
322 |
+
function set_email_template($body) {
|
323 |
+
$template = '';
|
324 |
+
if (isset($this->options['template']) && !empty($this->options['template']))
|
325 |
+
$template .= $this->options['template'];
|
326 |
+
return str_replace('%content%', $body, $template);
|
327 |
+
}
|
328 |
+
|
329 |
+
/**
|
330 |
+
* Replaces sender email if set & valid
|
331 |
+
*
|
332 |
+
* @since 0.1
|
333 |
+
* @param string $from_email
|
334 |
+
* @return string
|
335 |
+
*/
|
336 |
+
function set_from_email($from_email) {
|
337 |
+
if (!empty($this->options['from_email']) && is_email($this->options['from_email']))
|
338 |
+
return $this->options['from_email'];
|
339 |
+
return $from_email;
|
340 |
+
}
|
341 |
+
|
342 |
+
/**
|
343 |
+
* Replaces sender name if set
|
344 |
+
*
|
345 |
+
* @since 0.1
|
346 |
+
* @param string $from_name
|
347 |
+
* @return string
|
348 |
+
*/
|
349 |
+
function set_from_name($from_name) {
|
350 |
+
if (!empty($this->options['from_name']))
|
351 |
+
return wp_specialchars_decode($this->options['from_name'], ENT_QUOTES);
|
352 |
+
return $from_name;
|
353 |
+
}
|
354 |
+
|
355 |
+
/**
|
356 |
+
* Always set content type to HTML
|
357 |
+
*
|
358 |
+
* @since 0.1
|
359 |
+
* @param string $content_type
|
360 |
+
* @return string $content_type
|
361 |
+
*/
|
362 |
+
function set_content_type($content_type) {
|
363 |
+
// Only convert if the message is text/plain and the template is ok
|
364 |
+
if ($content_type == 'text/plain' && $this->check_template() === true) {
|
365 |
+
add_action('phpmailer_init', array(&$this, 'send_html'));
|
366 |
+
return $content_type = 'text/html';
|
367 |
+
}
|
368 |
+
return $content_type;
|
369 |
+
}
|
370 |
+
|
371 |
+
/**
|
372 |
+
* Add the email template and set it multipart
|
373 |
+
*
|
374 |
+
* @since 0.1
|
375 |
+
* @param object $phpmailer
|
376 |
+
*/
|
377 |
+
function send_html($phpmailer) {
|
378 |
+
// Set the original plain text message
|
379 |
+
$phpmailer->AltBody = wp_specialchars_decode($phpmailer->Body, ENT_QUOTES);
|
380 |
+
// Clean < and > around text links in WP 3.1
|
381 |
+
$phpmailer->Body = $this->esc_textlinks($phpmailer->Body);
|
382 |
+
// Convert line breaks & make links clickable
|
383 |
+
$phpmailer->Body = nl2br(make_clickable($phpmailer->Body));
|
384 |
+
// Add template to message
|
385 |
+
$phpmailer->Body = $this->set_email_template($phpmailer->Body);
|
386 |
+
// Replace variables in email
|
387 |
+
$phpmailer->Body = $this->template_vars_replacement($phpmailer->Body);
|
388 |
+
}
|
389 |
+
|
390 |
+
/**
|
391 |
+
* Replaces the < & > of the 3.1 email text links
|
392 |
+
*
|
393 |
+
* @since 0.1.2
|
394 |
+
* @param string $body
|
395 |
+
* @return string
|
396 |
+
*/
|
397 |
+
function esc_textlinks($body) {
|
398 |
+
return preg_replace('#<(https?://[^*]+)>#', '$1', $body);
|
399 |
+
}
|
400 |
+
|
401 |
+
/**
|
402 |
+
* Help on template variables in contextual help
|
403 |
+
*
|
404 |
+
* @since 0.2
|
405 |
+
* @global string $page
|
406 |
+
* @param string $contextual_help
|
407 |
+
* @param string $screen_id
|
408 |
+
* @param string $screen
|
409 |
+
*/
|
410 |
+
function contextual_help($contextual_help, $screen_id, $screen) {
|
411 |
+
if (!$this->is_wpbe_page())
|
412 |
+
return $contextual_help;
|
413 |
+
return '<p>' . __('Some dynamic tags can be included in your email template :', 'wp-better-emails') . '</p>
|
414 |
+
<ul>
|
415 |
+
<li>' . __('<strong>%content%</strong> : will be replaced with the message content.', 'wp-better-emails') . '<br />
|
416 |
+
<span class="description"> ' . __('NOTE: The content tag is <strong>required</strong>, WP Better Emails will be automatically desactivated if no content tag is found.', 'wp-better-emails') . '</span></li>
|
417 |
+
<li>' . __('<strong>%blog_url%</strong> : will be replaced with your blog URL.', 'wp-better-emails') . '</li>
|
418 |
+
<li>' . __('<strong>%home_url%</strong> : will be replaced with your home URL.', 'wp-better-emails') . '</li>
|
419 |
+
<li>' . __('<strong>%blog_name%</strong> : will be replaced with your blog name.', 'wp-better-emails') . '</li>
|
420 |
+
<li>' . __('<strong>%blog_description%</strong> : will be replaced with your blog description.', 'wp-better-emails') . '</li>
|
421 |
+
<li>' . __('<strong>%admin_email%</strong> : will be replaced with admin email.', 'wp-better-emails') . '</li>
|
422 |
+
<li>' . __('<strong>%date%</strong> : will be replaced with current date, as formatted in <a href="options-general.php">general options</a>.', 'wp-better-emails') . '</li>
|
423 |
+
<li>' . __('<strong>%time%</strong> : will be replaced with current time, as formatted in <a href="options-general.php">general options</a>.', 'wp-better-emails') . '</li>
|
424 |
+
</ul>';
|
425 |
+
}
|
426 |
+
|
427 |
+
/**
|
428 |
+
* TinyMCE plugins
|
429 |
+
*
|
430 |
+
* Editing HTML emails requires some more plugins from TinyMCE:
|
431 |
+
* - fullpage to handle html, meta, body tags
|
432 |
+
* - codemirror for editing source
|
433 |
+
*
|
434 |
+
* @since 0.2
|
435 |
+
* @param array $external_plugins
|
436 |
+
* @return array
|
437 |
+
*/
|
438 |
+
function tinymce_plugins($external_plugins) {
|
439 |
+
global $wp_version;
|
440 |
+
if (!$this->is_wpbe_page())
|
441 |
+
return $external_plugins;
|
442 |
+
|
443 |
+
$fullpage = array();
|
444 |
+
if (version_compare($wp_version, '3.2', '<'))
|
445 |
+
$fullpage = array('fullpage' => plugins_url('tinymce-plugins/3.3.x/fullpage/editor_plugin.js', __FILE__));
|
446 |
+
else
|
447 |
+
$fullpage = array('fullpage' => plugins_url('tinymce-plugins/3.4.x/fullpage/editor_plugin.js', __FILE__));
|
448 |
+
|
449 |
+
$cmseditor = array('cmseditor' => plugins_url('tinymce-plugins/cmseditor/editor_plugin.js', __FILE__));
|
450 |
+
$external_plugins = $external_plugins + $fullpage + $cmseditor;
|
451 |
+
return $external_plugins;
|
452 |
+
}
|
453 |
+
|
454 |
+
/**
|
455 |
+
* Button to the TinyMCE toolbar
|
456 |
+
*
|
457 |
+
* @since 0.2
|
458 |
+
* @global string $page
|
459 |
+
* @global type $page_hook
|
460 |
+
* @param type $buttons
|
461 |
+
* @return type
|
462 |
+
*/
|
463 |
+
function tinymce_buttons($buttons) {
|
464 |
+
if ($this->is_wpbe_page())
|
465 |
+
array_push($buttons, 'cmseditor');
|
466 |
+
return $buttons;
|
467 |
+
}
|
468 |
+
|
469 |
+
/**
|
470 |
+
* Prevent TinyMCE from removing line breaks
|
471 |
+
*
|
472 |
+
* @param array $init
|
473 |
+
* @return boolean
|
474 |
+
*/
|
475 |
+
function tinymce_config($init) {
|
476 |
+
if (!$this->is_wpbe_page())
|
477 |
+
return $init;
|
478 |
+
$init['remove_linebreaks'] = false;
|
479 |
+
$init['content_css'] = ''; // WP =< 3.0
|
480 |
+
if ( isset($init['extended_valid_elements']) )
|
481 |
+
$init['extended_valid_elements'] = $init['extended_valid_elements'] . ',td[*]';
|
482 |
+
return $init;
|
483 |
+
}
|
484 |
+
|
485 |
+
/**
|
486 |
+
* Load WP tinyMCE editor
|
487 |
+
*
|
488 |
+
* @since 0.2
|
489 |
+
*/
|
490 |
+
function load_wp_tiny_mce() {
|
491 |
+
if (!$this->is_wpbe_page())
|
492 |
+
return;
|
493 |
+
$settings = array(
|
494 |
+
'editor_selector' => 'wpbe_template',
|
495 |
+
'height' => '400'
|
496 |
+
);
|
497 |
+
wp_tiny_mce(false, $settings);
|
498 |
+
}
|
499 |
+
|
500 |
+
/**
|
501 |
+
* Print WP TinyMCE editor to edit template
|
502 |
+
*
|
503 |
+
* @since 0.2
|
504 |
+
* @global string $wp_version
|
505 |
+
*/
|
506 |
+
function template_editor() {
|
507 |
+
global $wp_version;
|
508 |
+
|
509 |
+
if (version_compare($wp_version, '3.3', '<')) {
|
510 |
+
?>
|
511 |
+
<textarea id="wpbe_template" class="wpbe_template" name="wpbe_options[template]" cols="80" rows="10"><?php echo $this->options['template']; ?></textarea>
|
512 |
+
<?php
|
513 |
+
} else {
|
514 |
+
// WP >= 3.3
|
515 |
+
$settings = array('wpautop' => false, 'editor_class' => 'wpbe_template', 'quicktags' => true);
|
516 |
+
wp_editor($template, 'wpbe_options[template]', $settings);
|
517 |
+
}
|
518 |
+
}
|
519 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
520 |
}
|
|
|
|
|
521 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
522 |
}
|
523 |
|
524 |
+
if (class_exists('WP_Better_Emails')) {
|
525 |
+
$wp_better_emails = new WP_Better_Emails();
|
526 |
+
register_activation_hook(__FILE__, array($wp_better_emails, 'install'));
|
|
|
|
|
|
|
|
|
|
|
|
|
527 |
}
|
528 |
?>
|
wpbe_template.html
DELETED
@@ -1,47 +0,0 @@
|
|
1 |
-
<html>
|
2 |
-
<body bgcolor="#f9f9f9" link="#21759B" alink="#21759B" vlink="#21759B" marginheight="0" topmargin="0" marginwidth="0" leftmargin="0" style="margin: 0px; background-color: #f9f9f9; font-family: Helvetica, Arial, sans-serif;">
|
3 |
-
<table cellpadding="0" cellspacing="0" width="100%" bgcolor="#f9f9f9" border="0">
|
4 |
-
<tr>
|
5 |
-
<td style="padding:15px;" align="center">
|
6 |
-
<center>
|
7 |
-
<table width="550" cellpadding="0" bgcolor="#ffffff" cellspacing="0" >
|
8 |
-
<tr>
|
9 |
-
<td>
|
10 |
-
<div style="border:solid 1px #d9d9d9;">
|
11 |
-
<table id="header" width="100%;" border="0" cellpadding="0" bgcolor="#ffffff" cellspacing="0" style="line-height:1.5;font-size:12px;font-family: Helvetica, Arial, sans-serif;border:solid 1px #FFFFFF;">
|
12 |
-
<tr>
|
13 |
-
<td colspan="2" background="%blog_url%/wp-admin/images/white-grad-active.png" height="30"> </td>
|
14 |
-
</tr>
|
15 |
-
<tr >
|
16 |
-
<td style="line-height:32px;padding: 0 0 0 30px;" valign="baseline">
|
17 |
-
<span style="font-size:32px;"><a href="%blog_url%" style="text-decoration:none;" target="_blank">%blog_name%</a></span>
|
18 |
-
</td>
|
19 |
-
<td style="padding: 0 30px 0 0;" align="right" valign="baseline">
|
20 |
-
<span style="font-size:14px;color:#777777">%blog_description%</span>
|
21 |
-
</td>
|
22 |
-
</tr>
|
23 |
-
</table>
|
24 |
-
<table id="content" width="100%;" border="0" cellpadding="0" bgcolor="#ffffff" cellspacing="0" style="color:#444;line-height:1.5;font-size:12px;font-family: Arial, sans-serif;padding:20px 30px 0 30px;">
|
25 |
-
<tr>
|
26 |
-
<td colspan="2" style="padding:20px 0;border-top: solid 1px #d9d9d9">%content%</td>
|
27 |
-
</tr>
|
28 |
-
</table>
|
29 |
-
<table id="footer" width="100%;" border="0" cellpadding="0" bgcolor="#ffffff" cellspacing="0" style="line-height:1.5;font-size:12px;font-family: Arial, sans-serif;padding:0 30px 15px 30px;">
|
30 |
-
<tr style="font-size:11px;color:#777777;">
|
31 |
-
<td style="border-top: solid 1px #d9d9d9;" colspan="2">
|
32 |
-
<img style="padding:15px 0 0 0" height="32" width="32" src="%blog_url%/wp-admin/images/wp-logo.png" align="right" alt="Powered by Wordpress" />
|
33 |
-
<div style="padding:15px 0 1px 0"><img height="13" width="13" style="vertical-align: middle;" src="%blog_url%/wp-admin/images/date-button.gif" alt="Date" /> Email sent the %date% @ %time%</div>
|
34 |
-
<div><img height="12" width="12" style="vertical-align: middle;" src="%blog_url%/wp-admin/images/comment-grey-bubble.png" alt="Request" /> For any request, please contact <a href="mailto:%admin_email%">%admin_email%</a></div>
|
35 |
-
</td>
|
36 |
-
</tr>
|
37 |
-
</table>
|
38 |
-
</div>
|
39 |
-
</td>
|
40 |
-
</tr>
|
41 |
-
</table>
|
42 |
-
</center>
|
43 |
-
</td>
|
44 |
-
</tr>
|
45 |
-
</table>
|
46 |
-
</body>
|
47 |
-
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|