test
This commit is contained in:
parent
6082eca117
commit
41823fbddf
28
Gemfile.lock
28
Gemfile.lock
|
@ -19,6 +19,7 @@ PATH
|
|||
rails
|
||||
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actionmailer (3.2.13)
|
||||
|
@ -61,6 +62,10 @@ GEM
|
|||
xpath (~> 1.0.0)
|
||||
childprocess (0.5.3)
|
||||
ffi (~> 1.0, >= 1.0.11)
|
||||
climate_control (0.0.3)
|
||||
activesupport (>= 3.0)
|
||||
cocaine (0.5.4)
|
||||
climate_control (>= 0.0.3, < 1.0)
|
||||
coderay (1.0.9)
|
||||
coffee-rails (3.2.2)
|
||||
coffee-script (>= 2.2.0)
|
||||
|
@ -74,12 +79,16 @@ GEM
|
|||
fastercsv (1.5.0)
|
||||
ffi (1.9.3-x86-mingw32)
|
||||
hike (1.2.3)
|
||||
htmlentities (4.3.2)
|
||||
i18n (0.6.1)
|
||||
journey (1.0.4)
|
||||
jquery-rails (2.0.3)
|
||||
railties (>= 3.1.0, < 5.0)
|
||||
thor (~> 0.14)
|
||||
json (1.8.0)
|
||||
kaminari (0.16.1)
|
||||
actionpack (>= 3.0.0)
|
||||
activesupport (>= 3.0.0)
|
||||
mail (2.5.4)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
|
@ -91,6 +100,11 @@ GEM
|
|||
mysql2 (0.3.11-x86-mingw32)
|
||||
net-ldap (0.3.1)
|
||||
nokogiri (1.5.11-x86-mingw32)
|
||||
paperclip (3.5.4)
|
||||
activemodel (>= 3.0.0)
|
||||
activesupport (>= 3.0.0)
|
||||
cocaine (~> 0.5.3)
|
||||
mime-types
|
||||
polyglot (0.3.3)
|
||||
rack (1.4.5)
|
||||
rack-cache (1.2)
|
||||
|
@ -98,6 +112,8 @@ GEM
|
|||
rack-openid (1.3.1)
|
||||
rack (>= 1.1.0)
|
||||
ruby-openid (>= 2.1.8)
|
||||
rack-raw-upload (1.1.1)
|
||||
multi_json
|
||||
rack-ssl (1.3.3)
|
||||
rack
|
||||
rack-test (0.6.2)
|
||||
|
@ -120,6 +136,14 @@ GEM
|
|||
rake (10.3.2)
|
||||
rdoc (3.12.2)
|
||||
json (~> 1.4)
|
||||
rich (1.4.6)
|
||||
jquery-rails
|
||||
kaminari
|
||||
mime-types
|
||||
paperclip
|
||||
rack-raw-upload
|
||||
rails (>= 3.2.0)
|
||||
sass-rails
|
||||
rmagick (2.13.2)
|
||||
ruby-openid (2.1.8)
|
||||
rubyzip (1.1.4)
|
||||
|
@ -170,15 +194,19 @@ DEPENDENCIES
|
|||
coderay (~> 1.0.6)
|
||||
coffee-rails (~> 3.2.1)
|
||||
fastercsv (~> 1.5.0)
|
||||
htmlentities
|
||||
i18n (~> 0.6.0)
|
||||
jquery-rails (~> 2.0.2)
|
||||
kaminari
|
||||
mocha (~> 0.13.3)
|
||||
mysql2 (= 0.3.11)
|
||||
net-ldap (~> 0.3.1)
|
||||
nokogiri (< 1.6.0)
|
||||
paperclip (~> 3.5.4)
|
||||
rack-mini-profiler!
|
||||
rack-openid
|
||||
rails (= 3.2.13)
|
||||
rich (= 1.4.6)
|
||||
rmagick (>= 2.0.0)
|
||||
ruby-openid (~> 2.1.4)
|
||||
sass-rails (~> 3.2.3)
|
||||
|
|
15
ReadMe.txt
15
ReadMe.txt
|
@ -51,3 +51,18 @@ app\controller\welcome_controller.rb
|
|||
user_scores表结构有问题,需要运行
|
||||
bundle exec rake db:migrate:down VERSION=20140410021724
|
||||
bundle exec rake db:migrate:up VERSION=20140410021724
|
||||
===============================================================================
|
||||
0708:CKEditor插件加载方法
|
||||
1.把插件文件夹拷入plugins文件夹,确保文件夹名为redmine_ckeditor
|
||||
2.运行 bundle install --without development test
|
||||
3.运行 rake redmine:plugins:migrate RAILS_ENV=production
|
||||
4.启动服务器
|
||||
5.把文本格式 (Administration > Settings > General > Text formatting)改为CKEditor
|
||||
6.配置CKEditor插件(Administration > Plugins > Configure)
|
||||
|
||||
某些情况数据库未插入插件配置值解决方案:
|
||||
1 复制plugins
|
||||
2 启动rails
|
||||
3 运行migrate
|
||||
3 打开admin配置插件(http://127.0.0.1:3000/settings/plugin/redmine_ckeditor)
|
||||
4 点击“查询”(就是确定的功能)
|
|
@ -251,3 +251,15 @@ course_domain:
|
|||
default: course.trustie.net
|
||||
repository_domain:
|
||||
default: repository.trustie.net
|
||||
plugin_redmine_ckeditor:
|
||||
serialized: true
|
||||
default: --- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
|
||||
skin: moono
|
||||
ui_color: ! '#f4f4f4'
|
||||
width: ''
|
||||
height: '400'
|
||||
enter_mode: '1'
|
||||
show_blocks: '1'
|
||||
toolbar_can_collapse: '0'
|
||||
toolbar_location: top
|
||||
toolbar: Source,ShowBlocks,--,Undo,Redo,-,Find,Replace,--,Bold,Italic,Underline,Strike,-,Subscript,Superscript,-,NumberedList,BulletedList,-,Outdent,Indent,Blockquote,-,JustifyLeft,JustifyCenter,JustifyRight,JustifyBlock,-,Link,Unlink,-,richImage,Table,HorizontalRule,/,Styles,Format,Font,FontSize,-,TextColor,BGColor
|
||||
|
|
17
db/schema.rb
17
db/schema.rb
|
@ -11,7 +11,7 @@
|
|||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 20140708023356) do
|
||||
ActiveRecord::Schema.define(:version => 20140704034832) do
|
||||
|
||||
create_table "activities", :force => true do |t|
|
||||
t.integer "act_id", :null => false
|
||||
|
@ -794,7 +794,7 @@ ActiveRecord::Schema.define(:version => 20140708023356) do
|
|||
end
|
||||
|
||||
create_table "relative_memos", :force => true do |t|
|
||||
t.integer "osp_id"
|
||||
t.integer "osp_id", :null => false
|
||||
t.integer "parent_id"
|
||||
t.string "subject", :null => false
|
||||
t.text "content", :null => false
|
||||
|
@ -831,6 +831,19 @@ ActiveRecord::Schema.define(:version => 20140708023356) do
|
|||
|
||||
add_index "repositories", ["project_id"], :name => "index_repositories_on_project_id"
|
||||
|
||||
create_table "rich_rich_files", :force => true do |t|
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.string "rich_file_file_name"
|
||||
t.string "rich_file_content_type"
|
||||
t.integer "rich_file_file_size"
|
||||
t.datetime "rich_file_updated_at"
|
||||
t.string "owner_type"
|
||||
t.integer "owner_id"
|
||||
t.text "uri_cache"
|
||||
t.string "simplified_type", :default => "file"
|
||||
end
|
||||
|
||||
create_table "roles", :force => true do |t|
|
||||
t.string "name", :limit => 30, :default => "", :null => false
|
||||
t.integer "position", :default => 1
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "app/assets/javascripts/ckeditor-releases"]
|
||||
path = app/assets/javascripts/ckeditor-releases
|
||||
url = git://github.com/ckeditor/ckeditor-releases.git
|
|
@ -0,0 +1,6 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
gem 'rich', '1.4.6'
|
||||
gem 'kaminari'
|
||||
gem 'htmlentities'
|
||||
gem 'paperclip', '~> 3.5.4'
|
|
@ -0,0 +1,69 @@
|
|||
= Redmine CKEditor plugin
|
||||
|
||||
This plugin adds the text formatting for using CKEditor to Redmine.
|
||||
|
||||
Since version 1.0.0, it includes {Rich}[https://github.com/bastiaanterhorst/rich] and supports image uploads.
|
||||
|
||||
== What is CKEditor?
|
||||
|
||||
CKEditor is a WYSIWYG text editor.
|
||||
See {the official site}[http://ckeditor.com/] for more details.
|
||||
|
||||
== Requirements
|
||||
|
||||
* Redmine 2.3.x, Ruby 1.9.2 or higher, {ImageMagick}[http://www.imagemagick.org/] (version {1.0.16}[https://github.com/a-ono/redmine_ckeditor])
|
||||
# Ubuntu
|
||||
apt-get install imagemagick
|
||||
# Mac OS X
|
||||
brew install imagemagick
|
||||
|
||||
* Redmine 2.3.x (version {0.4.0}[https://github.com/a-ono/redmine_ckeditor/tree/0.4.0])
|
||||
|
||||
* Redmine 2.2.x (version {0.3.0}[https://github.com/a-ono/redmine_ckeditor/tree/0.3.0])
|
||||
|
||||
* Redmine 2.1.x (version {0.2.1}[https://github.com/a-ono/redmine_ckeditor/tree/0.2.1])
|
||||
|
||||
* Redmine 2.0.x (version {0.1.1}[https://github.com/a-ono/redmine_ckeditor/tree/0.1.1])
|
||||
|
||||
* Redmine 1.1.0 - 1.4.2 (version {0.0.6}[https://github.com/a-ono/redmine_ckeditor/tree/0.0.6])
|
||||
|
||||
== Plugin installation and setup
|
||||
|
||||
1. Copy the plugin directory into the plugins directory (make sure the name is redmine_ckeditor)
|
||||
2. Install the required gems (in the Redmine root directory)
|
||||
bundle install --without development test
|
||||
3. Execute migration
|
||||
rake redmine:plugins:migrate RAILS_ENV=production
|
||||
4. Start Redmine
|
||||
5. Change text formatting (Administration > Settings > General > Text formatting) to CKEditor
|
||||
6. Configure the plugin (Administration > Plugins > Configure)
|
||||
|
||||
=== Upgrade
|
||||
|
||||
1. Replace the plugin directory (plugins/redmine_ckeditor)
|
||||
2. Install the required gems
|
||||
bundle install --without development test
|
||||
3. Execute migration
|
||||
rake redmine:plugins:migrate RAILS_ENV=production
|
||||
4. Delete old assets
|
||||
rm -r /public/plugin_assets/redmine_ckeditor
|
||||
5. Restart Redmine
|
||||
|
||||
== CKEditor customization
|
||||
|
||||
=== Plugins
|
||||
|
||||
You can download plugins from {Add-ons Repository}[http://ckeditor.com/addons/plugins/all].
|
||||
To activate the plugin you have to copy the plugin directory into assets/ckeditor-contrib/plugins and restart Redmine, then configure toolbar settings.
|
||||
|
||||
=== Skins
|
||||
|
||||
You can select third-party skins placed in assets/ckeditor-contrib/skins directory.
|
||||
|
||||
== Migration notes
|
||||
|
||||
This plugin stores contents in HTML format and renders as is.
|
||||
If you have old contents, these look weird.
|
||||
|
||||
You can use {redmine_per_project_formatting}[https://github.com/a-ono/redmine_per_project_formatting] plugin for backward compatibility or execute redmine_ckeditor:migrate task for migrating old text to HTML.
|
||||
rake redmine_ckeditor:migrate RAILS_ENV=production [PROJECT=project_identifier1,project_identifier2] [FORMAT=textile]
|
|
@ -0,0 +1,5 @@
|
|||
//
|
||||
//= require rich/editor/ckeditor_path
|
||||
//= require ckeditor-releases/ckeditor
|
||||
//= require rich/editor/rich_editor
|
||||
//= require rich/editor/rich_picker
|
|
@ -0,0 +1,4 @@
|
|||
//= require fileuploader
|
||||
//= require rich/browser/extensions
|
||||
//= require rich/browser/uploader
|
||||
//= require rich/browser/filebrowser
|
|
@ -0,0 +1,69 @@
|
|||
class RedmineCkeditorSetting
|
||||
def self.setting
|
||||
Setting[:plugin_redmine_ckeditor] || {}
|
||||
end
|
||||
|
||||
def self.default
|
||||
["1", true].include?(setting[:default])
|
||||
end
|
||||
|
||||
def self.toolbar_string
|
||||
setting[:toolbar] || RedmineCkeditor.default_toolbar
|
||||
end
|
||||
|
||||
def self.toolbar
|
||||
bars = []
|
||||
bar = []
|
||||
toolbar_string.split(",").each {|item|
|
||||
case item
|
||||
when '/'
|
||||
bars.push(bar, item)
|
||||
bar = []
|
||||
when '--'
|
||||
bars.push(bar)
|
||||
bar = []
|
||||
else
|
||||
bar.push(item)
|
||||
end
|
||||
}
|
||||
|
||||
bars.push(bar) unless bar.empty?
|
||||
bars
|
||||
end
|
||||
|
||||
def self.skin
|
||||
setting[:skin] || "moono"
|
||||
end
|
||||
|
||||
def self.ui_color
|
||||
setting[:ui_color] || "#f4f4f4"
|
||||
end
|
||||
|
||||
def self.enter_mode
|
||||
(setting[:enter_mode] || 1).to_i
|
||||
end
|
||||
|
||||
def self.shift_enter_mode
|
||||
enter_mode == 2 ? 1 : 2
|
||||
end
|
||||
|
||||
def self.show_blocks
|
||||
(setting[:show_blocks] || 1).to_i == 1
|
||||
end
|
||||
|
||||
def self.toolbar_can_collapse
|
||||
setting[:toolbar_can_collapse].to_i == 1
|
||||
end
|
||||
|
||||
def self.toolbar_location
|
||||
setting[:toolbar_location] || "top"
|
||||
end
|
||||
|
||||
def self.width
|
||||
setting[:width]
|
||||
end
|
||||
|
||||
def self.height
|
||||
setting[:height] || 400
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
<% if RedmineCkeditor.enabled? %>
|
||||
destroyEditor("issue_description");
|
||||
<% end %>
|
||||
|
||||
$('#all_attributes').html('<%= escape_javascript(render :partial => 'form') %>');
|
||||
|
||||
<% if User.current.allowed_to?(:log_time, @issue.project) %>
|
||||
$('#log_time').show();
|
||||
<% else %>
|
||||
$('#log_time').hide();
|
||||
<% end %>
|
|
@ -0,0 +1,9 @@
|
|||
<%
|
||||
# when quoting a private journal, check the private checkbox
|
||||
if @journal && @journal.private_notes?
|
||||
%>
|
||||
$('#issue_private_notes').attr('checked', true);
|
||||
<% end %>
|
||||
|
||||
CKEDITOR.instances['issue_notes'].setData(<%= @content.inspect.html_safe %>);
|
||||
showAndScrollTo("update", "issue_notes");
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Rich Browser</title>
|
||||
<%= javascript_heads %>
|
||||
<%= stylesheet_link_tag "application", :plugin => "redmine_ckeditor" %>
|
||||
<%= ckeditor_javascripts %>
|
||||
<%= javascript_include_tag "browser", :plugin => "redmine_ckeditor" %>
|
||||
<%= csrf_meta_tags %>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<%= yield %>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,2 @@
|
|||
<%= render :file => "messages/quote" %>
|
||||
CKEDITOR.instances['message_content'].setData($('#message_content').val());
|
|
@ -0,0 +1,12 @@
|
|||
<li class="clickable">
|
||||
<img id="file<%= file.id %>"
|
||||
src="<%= thumb_for_file(file) %>"
|
||||
data-uris="<%= file.uri_cache %>"
|
||||
data-relative-url-root="<%= Redmine::Utils.relative_url_root %>"
|
||||
data-rich-asset-id="<%= file.id %>"
|
||||
data-rich-asset-type="<%= file.simplified_type %>"
|
||||
data-rich-asset-name="<%= file.rich_file_file_name %>"
|
||||
/>
|
||||
<p><%= file.rich_file_file_name %></p>
|
||||
<%= link_to "delete", file.id.to_s, :method => :delete, :remote => true, :confirm => t(:delete_confirm), :class => "delete", :title => t(:delete) %>
|
||||
</li>
|
|
@ -0,0 +1,142 @@
|
|||
<%= ckeditor_javascripts %>
|
||||
<%= stylesheet_link_tag 'editor', :plugin => 'redmine_ckeditor'%>
|
||||
<%= stylesheet_link_tag 'selector', :plugin => 'redmine_ckeditor'%>
|
||||
<p>
|
||||
<%= content_tag :label, l(:ckeditor_skin) %>
|
||||
<%= select_tag "settings[skin]", RedmineCkeditor.skin_options %>
|
||||
</p>
|
||||
<p>
|
||||
<%= content_tag :label, l(:ckeditor_ui_color) %>
|
||||
<%= text_field_tag "settings[ui_color]", RedmineCkeditorSetting.ui_color %>
|
||||
</p>
|
||||
<p>
|
||||
<%= content_tag :label, l(:ckeditor_width) %>
|
||||
<%= text_field_tag "settings[width]", RedmineCkeditorSetting.width %>
|
||||
</p>
|
||||
<p>
|
||||
<%= content_tag :label, l(:ckeditor_height) %>
|
||||
<%= text_field_tag "settings[height]", RedmineCkeditorSetting.height %>
|
||||
</p>
|
||||
<p>
|
||||
<%= content_tag :label, l(:ckeditor_enter_mode) %>
|
||||
<%= select_tag "settings[enter_mode]", RedmineCkeditor.enter_mode_options %>
|
||||
</p>
|
||||
<p>
|
||||
<%= content_tag :label, l(:ckeditor_startup_show_blocks) %>
|
||||
<%= hidden_field_tag "settings[show_blocks]", 0 %>
|
||||
<%= check_box_tag "settings[show_blocks]", 1, RedmineCkeditorSetting.show_blocks %>
|
||||
</p>
|
||||
<p>
|
||||
<%= content_tag :label, l(:ckeditor_toolbar_can_collapse) %>
|
||||
<%= hidden_field_tag "settings[toolbar_can_collapse]", 0 %>
|
||||
<%= check_box_tag "settings[toolbar_can_collapse]", 1, RedmineCkeditorSetting.toolbar_can_collapse %>
|
||||
</p>
|
||||
<p>
|
||||
<%= content_tag :label, l(:ckeditor_toolbar_location) %>
|
||||
<%= select_tag "settings[toolbar_location]", RedmineCkeditor.toolbar_location_options %>
|
||||
</p>
|
||||
<p>
|
||||
<%= content_tag :label, l(:ckeditor_toolbar_buttons) %>
|
||||
</p>
|
||||
|
||||
<div class="selector-container">
|
||||
<%= hidden_field_tag "settings[toolbar]", RedmineCkeditorSetting.toolbar_string %>
|
||||
|
||||
<select id="left" multiple="multiple" size="10">
|
||||
</select>
|
||||
|
||||
<div class="container">
|
||||
<input type="button" class="button" value="<%= t(:add) %> >>"
|
||||
onclick="moveItem('left', 'right')"/><br/>
|
||||
<input type="button" class="button" value="<%= t(:remove) %> <<"
|
||||
onclick="moveItem('right', 'left')"/><br/><br/>
|
||||
<input type="button" class="button" value="<%= t(:separator) %> >>"
|
||||
onclick="addItem('-')"/><br/>
|
||||
<input type="button" class="button" value="<%= t(:subgroup) %> >>"
|
||||
onclick="addItem('--')"/><br/>
|
||||
<input type="button" class="button" value="<%= t(:line_break) %> >>"
|
||||
onclick="addItem('/')"/>
|
||||
</div>
|
||||
|
||||
<select id="right" multiple="multiple" size="10">
|
||||
</select>
|
||||
|
||||
<div class="clear"></div>
|
||||
<div id="toolbar"></div>
|
||||
</div>
|
||||
|
||||
<%= javascript_tag do %>
|
||||
function moveItem(from, to) {
|
||||
from = $("#" + from);
|
||||
to = $("#" + to);
|
||||
var selected = to.find("option:selected").first();
|
||||
from.find("option:selected").remove().each(function() {
|
||||
if (this.value == '-' || this.value == '--' || this.value == '/') return;
|
||||
selected.size() ? selected.before(this) : to.append(this);
|
||||
});
|
||||
to.prop("selectedIndex", -1);
|
||||
changeHandler();
|
||||
}
|
||||
|
||||
function addItem(item) {
|
||||
var option = $("<option/>").val(item).text(item);
|
||||
var to = $("#right");
|
||||
var selected = to.find("option:selected").first();
|
||||
selected.size() ? selected.before(option) : to.append(option);
|
||||
changeHandler();
|
||||
}
|
||||
|
||||
function changeHandler() {
|
||||
var values = $("#right").find("option").map(function() {
|
||||
return this.value;
|
||||
});
|
||||
$("#settings_toolbar").val(values.toArray().join(","));
|
||||
|
||||
var bars = [];
|
||||
var bar = [];
|
||||
values.each(function() {
|
||||
var value = this.toString();
|
||||
if (value == "/") {
|
||||
bars.push(bar, value);
|
||||
bar = [];
|
||||
} else if (value == "--") {
|
||||
bars.push(bar);
|
||||
bar = [];
|
||||
} else {
|
||||
bar.push(value);
|
||||
}
|
||||
});
|
||||
if (bar.length > 0) bars.push(bar);
|
||||
|
||||
CKEDITOR.instances['toolbar'].destroy();
|
||||
updateCkeditor(bars);
|
||||
}
|
||||
|
||||
function updateCkeditor(toolbar) {
|
||||
var options = <%= RedmineCkeditor.options.to_json.html_safe %>;
|
||||
options.toolbar = toolbar;
|
||||
CKEDITOR.replace('toolbar', options);
|
||||
}
|
||||
|
||||
CKEDITOR.on('instanceReady', function() {
|
||||
CKEDITOR.removeListener('instanceReady', arguments.callee);
|
||||
|
||||
var left = $("#left");
|
||||
var right = $("#right");
|
||||
var rightItems = $("#settings_toolbar").val().split(",");
|
||||
|
||||
var dict = {};
|
||||
$.each(CKEDITOR.instances.toolbar.ui.items, function(key, value) {
|
||||
if (key == '-') return;
|
||||
dict[key] = value.label;
|
||||
if (rightItems.indexOf(key) < 0) {
|
||||
left.append($("<option/>").val(key).text(dict[key] || key));
|
||||
}
|
||||
});
|
||||
$.each(rightItems, function() {
|
||||
right.append($("<option/>").val(this).text(dict[this] || this));
|
||||
});
|
||||
});
|
||||
|
||||
updateCkeditor(<%= RedmineCkeditorSetting.toolbar.to_json.html_safe %>);
|
||||
<% end %>
|
|
@ -0,0 +1,112 @@
|
|||
/* Extra for the CKEditor CodeMirror Plugin */
|
||||
|
||||
.CodeMirror {font:13px/1.4em monospace;}
|
||||
|
||||
.CodeMirror .activeline { background: #e8f2ff; }
|
||||
|
||||
.CodeMirror .CodeMirror-foldmarker {
|
||||
color: blue;
|
||||
text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px;
|
||||
font-family: arial;
|
||||
line-height: .3;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Fixes for themes */
|
||||
.cm-s-cobalt .CodeMirror-selected { background: #b36539 !important; }
|
||||
.cm-s-erlang-dark .CodeMirror-selected { background: #b36539 !important; }
|
||||
.cm-s-lesser-dark .CodeMirror-selected {background: #45443B !important;}
|
||||
.cm-s-monokai .CodeMirror-selected {background: #49483E !important;}
|
||||
.cm-s-night .CodeMirror-selected { background: #447 !important; }
|
||||
.cm-s-rubyblue .CodeMirror-selected { background: #38566F !important; }
|
||||
.cm-s-twilight .CodeMirror-selected { background: #323232 !important; }
|
||||
.cm-s-xq-dark .CodeMirror-selected { background: #a8f !important; }
|
||||
|
||||
.cm-s-blackboard .activeline,
|
||||
.cm-s-cobalt .activeline,
|
||||
.cm-s-erlang-dark .activeline,
|
||||
.cm-s-lesser-dark .activeline,
|
||||
.cm-s-monokai .activeline,
|
||||
.cm-s-night .activeline,
|
||||
.cm-s-rubyblue .activeline,
|
||||
.cm-s-vibrant-ink .activeline,
|
||||
.cm-s-xq-dark .activeline { background: #757575; }
|
||||
.cm-s-twilight .activeline { background:#494949; }
|
||||
|
||||
.CodeMirror-focused .cm-matchhighlight {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFklEQVQI12NgYGBgkKzc8x9CMDAwAAAmhwSbidEoSQAAAABJRU5ErkJggg==);
|
||||
background-position: bottom;
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
/* Dialog Addon */
|
||||
.CodeMirror-dialog {
|
||||
position: absolute;
|
||||
left: 0; right: 0;
|
||||
background: white;
|
||||
z-index: 15;
|
||||
padding: .1em .8em;
|
||||
overflow: hidden;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.CodeMirror-dialog-top {
|
||||
border-bottom: 1px solid #eee;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.CodeMirror-dialog-bottom {
|
||||
border-top: 1px solid #eee;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.CodeMirror-dialog input {
|
||||
border: none;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
width: 20em;
|
||||
color: inherit;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.CodeMirror-dialog button {
|
||||
font-size: 70%;
|
||||
}
|
||||
.CodeMirror-hints {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
overflow: hidden;
|
||||
list-style: none;
|
||||
|
||||
margin: 0;
|
||||
padding: 2px;
|
||||
|
||||
-webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
|
||||
-moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
|
||||
box-shadow: 2px 3px 5px rgba(0,0,0,.2);
|
||||
border-radius: 3px;
|
||||
border: 1px solid silver;
|
||||
|
||||
background: white;
|
||||
font-size: 90%;
|
||||
font-family: monospace;
|
||||
|
||||
max-height: 20em;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.CodeMirror-hint {
|
||||
margin: 0;
|
||||
padding: 0 4px;
|
||||
border-radius: 2px;
|
||||
max-width: 19em;
|
||||
overflow: hidden;
|
||||
white-space: pre;
|
||||
color: black;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.CodeMirror-hint-active {
|
||||
background: #08f;
|
||||
color: white;
|
||||
}
|
|
@ -0,0 +1,246 @@
|
|||
/* BASICS */
|
||||
|
||||
.CodeMirror {
|
||||
/* Set height, width, borders, and global font properties here */
|
||||
font-family: monospace;
|
||||
height: 300px;
|
||||
}
|
||||
.CodeMirror-scroll {
|
||||
/* Set scrolling behaviour here */
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* PADDING */
|
||||
|
||||
.CodeMirror-lines {
|
||||
padding: 4px 0; /* Vertical padding around content */
|
||||
}
|
||||
.CodeMirror pre {
|
||||
padding: 0 4px; /* Horizontal padding of content */
|
||||
}
|
||||
|
||||
.CodeMirror-scrollbar-filler {
|
||||
background-color: white; /* The little square between H and V scrollbars */
|
||||
}
|
||||
|
||||
/* GUTTER */
|
||||
|
||||
.CodeMirror-gutters {
|
||||
border-right: 1px solid #ddd;
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
.CodeMirror-linenumbers {}
|
||||
.CodeMirror-linenumber {
|
||||
padding: 0 3px 0 5px;
|
||||
min-width: 20px;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* CURSOR */
|
||||
|
||||
.CodeMirror div.CodeMirror-cursor {
|
||||
border-left: 1px solid black;
|
||||
z-index: 3;
|
||||
}
|
||||
/* Shown when moving in bi-directional text */
|
||||
.CodeMirror div.CodeMirror-secondarycursor {
|
||||
border-left: 1px solid silver;
|
||||
}
|
||||
.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor {
|
||||
width: auto;
|
||||
border: 0;
|
||||
background: #7e7;
|
||||
z-index: 1;
|
||||
}
|
||||
/* Can style cursor different in overwrite (non-insert) mode */
|
||||
.CodeMirror div.CodeMirror-cursor.CodeMirror-overwrite {}
|
||||
|
||||
.cm-tab { display: inline-block; }
|
||||
|
||||
/* DEFAULT THEME */
|
||||
|
||||
.cm-s-default .cm-keyword {color: #708;}
|
||||
.cm-s-default .cm-atom {color: #219;}
|
||||
.cm-s-default .cm-number {color: #164;}
|
||||
.cm-s-default .cm-def {color: #00f;}
|
||||
.cm-s-default .cm-variable {color: black;}
|
||||
.cm-s-default .cm-variable-2 {color: #05a;}
|
||||
.cm-s-default .cm-variable-3 {color: #085;}
|
||||
.cm-s-default .cm-property {color: black;}
|
||||
.cm-s-default .cm-operator {color: black;}
|
||||
.cm-s-default .cm-comment {color: #a50;}
|
||||
.cm-s-default .cm-string {color: #a11;}
|
||||
.cm-s-default .cm-string-2 {color: #f50;}
|
||||
.cm-s-default .cm-meta {color: #555;}
|
||||
.cm-s-default .cm-error {color: #f00;}
|
||||
.cm-s-default .cm-qualifier {color: #555;}
|
||||
.cm-s-default .cm-builtin {color: #30a;}
|
||||
.cm-s-default .cm-bracket {color: #997;}
|
||||
.cm-s-default .cm-tag {color: #170;}
|
||||
.cm-s-default .cm-attribute {color: #00c;}
|
||||
.cm-s-default .cm-header {color: blue;}
|
||||
.cm-s-default .cm-quote {color: #090;}
|
||||
.cm-s-default .cm-hr {color: #999;}
|
||||
.cm-s-default .cm-link {color: #00c;}
|
||||
|
||||
.cm-negative {color: #d44;}
|
||||
.cm-positive {color: #292;}
|
||||
.cm-header, .cm-strong {font-weight: bold;}
|
||||
.cm-em {font-style: italic;}
|
||||
.cm-link {text-decoration: underline;}
|
||||
|
||||
.cm-invalidchar {color: #f00;}
|
||||
|
||||
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
|
||||
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
|
||||
|
||||
/* STOP */
|
||||
|
||||
/* The rest of this file contains styles related to the mechanics of
|
||||
the editor. You probably shouldn't touch them. */
|
||||
|
||||
.CodeMirror {
|
||||
line-height: 1;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.CodeMirror-scroll {
|
||||
/* 30px is the magic margin used to hide the element's real scrollbars */
|
||||
/* See overflow: hidden in .CodeMirror, and the paddings in .CodeMirror-sizer */
|
||||
margin-bottom: -30px; margin-right: -30px;
|
||||
padding-bottom: 30px; padding-right: 30px;
|
||||
height: 100%;
|
||||
outline: none; /* Prevent dragging from highlighting the element */
|
||||
position: relative;
|
||||
}
|
||||
.CodeMirror-sizer {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* The fake, visible scrollbars. Used to force redraw during scrolling
|
||||
before actuall scrolling happens, thus preventing shaking and
|
||||
flickering artifacts. */
|
||||
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler {
|
||||
position: absolute;
|
||||
z-index: 6;
|
||||
display: none;
|
||||
}
|
||||
.CodeMirror-vscrollbar {
|
||||
right: 0; top: 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
.CodeMirror-hscrollbar {
|
||||
bottom: 0; left: 0;
|
||||
overflow-y: hidden;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
.CodeMirror-scrollbar-filler {
|
||||
right: 0; bottom: 0;
|
||||
z-index: 6;
|
||||
}
|
||||
|
||||
.CodeMirror-gutters {
|
||||
position: absolute; left: 0; top: 0;
|
||||
height: 100%;
|
||||
padding-bottom: 30px;
|
||||
z-index: 3;
|
||||
}
|
||||
.CodeMirror-gutter {
|
||||
height: 100%;
|
||||
padding-bottom: 30px;
|
||||
margin-bottom: -32px;
|
||||
display: inline-block;
|
||||
/* Hack to make IE7 behave */
|
||||
*zoom:1;
|
||||
*display:inline;
|
||||
}
|
||||
.CodeMirror-gutter-elt {
|
||||
position: absolute;
|
||||
cursor: default;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.CodeMirror-lines {
|
||||
cursor: text;
|
||||
}
|
||||
.CodeMirror pre {
|
||||
/* Reset some styles that the rest of the page might have set */
|
||||
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
|
||||
border-width: 0;
|
||||
background: transparent;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
margin: 0;
|
||||
white-space: pre;
|
||||
word-wrap: normal;
|
||||
line-height: inherit;
|
||||
color: inherit;
|
||||
z-index: 2;
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
}
|
||||
.CodeMirror-wrap pre {
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
word-break: normal;
|
||||
}
|
||||
.CodeMirror-linebackground {
|
||||
position: absolute;
|
||||
left: 0; right: 0; top: 0; bottom: 0;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.CodeMirror-linewidget {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.CodeMirror-widget {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.CodeMirror-wrap .CodeMirror-scroll {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.CodeMirror-measure {
|
||||
position: absolute;
|
||||
width: 100%; height: 0px;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
}
|
||||
.CodeMirror-measure pre { position: static; }
|
||||
|
||||
.CodeMirror div.CodeMirror-cursor {
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
border-right: none;
|
||||
width: 0;
|
||||
}
|
||||
.CodeMirror-focused div.CodeMirror-cursor {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.CodeMirror-selected { background: #d9d9d9; }
|
||||
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
|
||||
|
||||
.cm-searching {
|
||||
background: #ffa;
|
||||
background: rgba(255, 255, 0, .4);
|
||||
}
|
||||
|
||||
/* IE7 hack to prevent it from returning funny offsetTops on the spans */
|
||||
.CodeMirror span { *vertical-align: text-bottom; }
|
||||
|
||||
@media print {
|
||||
/* Hide the cursor when printing */
|
||||
.CodeMirror div.CodeMirror-cursor {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
1
plugins/redmine_ckeditor/assets/ckeditor-contrib/plugins/codemirror/css/codemirror.min.css
vendored
Normal file
1
plugins/redmine_ckeditor/assets/ckeditor-contrib/plugins/codemirror/css/codemirror.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 644 B |
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 490 B |
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
|
@ -0,0 +1,81 @@
|
|||
// Open simple dialogs on top of an editor. Relies on dialog.css.
|
||||
|
||||
(function() {
|
||||
function dialogDiv(cm, template, bottom) {
|
||||
var wrap = cm.getWrapperElement();
|
||||
var dialog;
|
||||
|
||||
dialog = wrap.appendChild(document.createElement("div"));
|
||||
if (bottom) {
|
||||
dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom";
|
||||
} else {
|
||||
dialog.className = "CodeMirror-dialog CodeMirror-dialog-top";
|
||||
}
|
||||
dialog.innerHTML = template;
|
||||
return dialog;
|
||||
}
|
||||
|
||||
CodeMirror.defineExtension("openDialog", function(template, callback, options) {
|
||||
var dialog = dialogDiv(this, template, options && options.bottom);
|
||||
var closed = false, me = this;
|
||||
function close() {
|
||||
if (closed) return;
|
||||
closed = true;
|
||||
dialog.parentNode.removeChild(dialog);
|
||||
}
|
||||
var inp = dialog.getElementsByTagName("input")[0], button;
|
||||
if (inp) {
|
||||
CodeMirror.on(inp, "keydown", function(e) {
|
||||
if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; }
|
||||
if (e.keyCode == 13 || e.keyCode == 27) {
|
||||
CodeMirror.e_stop(e);
|
||||
close();
|
||||
me.focus();
|
||||
if (e.keyCode == 13) callback(inp.value);
|
||||
}
|
||||
});
|
||||
if (options && options.onKeyUp) {
|
||||
CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);});
|
||||
}
|
||||
if (options && options.value) inp.value = options.value;
|
||||
inp.focus();
|
||||
CodeMirror.on(inp, "blur", close);
|
||||
} else if (button = dialog.getElementsByTagName("button")[0]) {
|
||||
CodeMirror.on(button, "click", function() {
|
||||
close();
|
||||
me.focus();
|
||||
});
|
||||
button.focus();
|
||||
CodeMirror.on(button, "blur", close);
|
||||
}
|
||||
return close;
|
||||
});
|
||||
|
||||
CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) {
|
||||
var dialog = dialogDiv(this, template, options && options.bottom);
|
||||
var buttons = dialog.getElementsByTagName("button");
|
||||
var closed = false, me = this, blurring = 1;
|
||||
function close() {
|
||||
if (closed) return;
|
||||
closed = true;
|
||||
dialog.parentNode.removeChild(dialog);
|
||||
me.focus();
|
||||
}
|
||||
buttons[0].focus();
|
||||
for (var i = 0; i < buttons.length; ++i) {
|
||||
var b = buttons[i];
|
||||
(function(callback) {
|
||||
CodeMirror.on(b, "click", function(e) {
|
||||
CodeMirror.e_preventDefault(e);
|
||||
close();
|
||||
if (callback) callback(me);
|
||||
});
|
||||
})(callbacks[i]);
|
||||
CodeMirror.on(b, "blur", function() {
|
||||
--blurring;
|
||||
setTimeout(function() { if (blurring <= 0) close(); }, 200);
|
||||
});
|
||||
CodeMirror.on(b, "focus", function() { ++blurring; });
|
||||
}
|
||||
});
|
||||
})();
|
|
@ -0,0 +1,52 @@
|
|||
(function() {
|
||||
var DEFAULT_BRACKETS = "()[]{}''\"\"";
|
||||
var SPACE_CHAR_REGEX = /\s/;
|
||||
|
||||
CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
|
||||
var wasOn = old && old != CodeMirror.Init;
|
||||
if (val && !wasOn)
|
||||
cm.addKeyMap(buildKeymap(typeof val == "string" ? val : DEFAULT_BRACKETS));
|
||||
else if (!val && wasOn)
|
||||
cm.removeKeyMap("autoCloseBrackets");
|
||||
});
|
||||
|
||||
function buildKeymap(pairs) {
|
||||
var map = {
|
||||
name : "autoCloseBrackets",
|
||||
Backspace: function(cm) {
|
||||
if (cm.somethingSelected()) return CodeMirror.Pass;
|
||||
var cur = cm.getCursor(), line = cm.getLine(cur.line);
|
||||
if (cur.ch && cur.ch < line.length &&
|
||||
pairs.indexOf(line.slice(cur.ch - 1, cur.ch + 1)) % 2 == 0)
|
||||
cm.replaceRange("", CodeMirror.Pos(cur.line, cur.ch - 1), CodeMirror.Pos(cur.line, cur.ch + 1));
|
||||
else
|
||||
return CodeMirror.Pass;
|
||||
}
|
||||
};
|
||||
var closingBrackets = [];
|
||||
for (var i = 0; i < pairs.length; i += 2) (function(left, right) {
|
||||
if (left != right) closingBrackets.push(right);
|
||||
function surround(cm) {
|
||||
var selection = cm.getSelection();
|
||||
cm.replaceSelection(left + selection + right);
|
||||
}
|
||||
function maybeOverwrite(cm) {
|
||||
var cur = cm.getCursor(), ahead = cm.getRange(cur, CodeMirror.Pos(cur.line, cur.ch + 1));
|
||||
if (ahead != right || cm.somethingSelected()) return CodeMirror.Pass;
|
||||
else cm.execCommand("goCharRight");
|
||||
}
|
||||
map["'" + left + "'"] = function(cm) {
|
||||
if (cm.somethingSelected()) return surround(cm);
|
||||
if (left == right && maybeOverwrite(cm) != CodeMirror.Pass) return;
|
||||
var cur = cm.getCursor(), ahead = CodeMirror.Pos(cur.line, cur.ch + 1);
|
||||
var line = cm.getLine(cur.line), nextChar = line.charAt(cur.ch);
|
||||
if (line.length == cur.ch || closingBrackets.indexOf(nextChar) >= 0 || SPACE_CHAR_REGEX.test(nextChar))
|
||||
cm.replaceSelection(left + right, {head: ahead, anchor: ahead});
|
||||
else
|
||||
return CodeMirror.Pass;
|
||||
};
|
||||
if (left != right) map["'" + right + "'"] = maybeOverwrite;
|
||||
})(pairs.charAt(i), pairs.charAt(i + 1));
|
||||
return map;
|
||||
}
|
||||
})();
|
|
@ -0,0 +1,85 @@
|
|||
/**
|
||||
* Tag-closer extension for CodeMirror.
|
||||
*
|
||||
* This extension adds an "autoCloseTags" option that can be set to
|
||||
* either true to get the default behavior, or an object to further
|
||||
* configure its behavior.
|
||||
*
|
||||
* These are supported options:
|
||||
*
|
||||
* `whenClosing` (default true)
|
||||
* Whether to autoclose when the '/' of a closing tag is typed.
|
||||
* `whenOpening` (default true)
|
||||
* Whether to autoclose the tag when the final '>' of an opening
|
||||
* tag is typed.
|
||||
* `dontCloseTags` (default is empty tags for HTML, none for XML)
|
||||
* An array of tag names that should not be autoclosed.
|
||||
* `indentTags` (default is block tags for HTML, none for XML)
|
||||
* An array of tag names that should, when opened, cause a
|
||||
* blank line to be added inside the tag, and the blank line and
|
||||
* closing line to be indented.
|
||||
*
|
||||
* See demos/closetag.html for a usage example.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
CodeMirror.defineOption("autoCloseTags", false, function(cm, val, old) {
|
||||
if (val && (old == CodeMirror.Init || !old)) {
|
||||
var map = {name: "autoCloseTags"};
|
||||
if (typeof val != "object" || val.whenClosing)
|
||||
map["'/'"] = function(cm) { return autoCloseTag(cm, '/'); };
|
||||
if (typeof val != "object" || val.whenOpening)
|
||||
map["'>'"] = function(cm) { return autoCloseTag(cm, '>'); };
|
||||
cm.addKeyMap(map);
|
||||
} else if (!val && (old != CodeMirror.Init && old)) {
|
||||
cm.removeKeyMap("autoCloseTags");
|
||||
}
|
||||
});
|
||||
|
||||
var htmlDontClose = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param",
|
||||
"source", "track", "wbr"];
|
||||
var htmlIndent = ["applet", "blockquote", "body", "button", "div", "dl", "fieldset", "form", "frameset", "h1", "h2", "h3", "h4",
|
||||
"h5", "h6", "head", "html", "iframe", "layer", "legend", "object", "ol", "p", "select", "table", "ul"];
|
||||
|
||||
function autoCloseTag(cm, ch) {
|
||||
var pos = cm.getCursor(), tok = cm.getTokenAt(pos);
|
||||
var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
|
||||
if (inner.mode.name != "xml") return CodeMirror.Pass;
|
||||
|
||||
var opt = cm.getOption("autoCloseTags"), html = inner.mode.configuration == "html";
|
||||
var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose);
|
||||
var indentTags = (typeof opt == "object" && opt.indentTags) || (html && htmlIndent);
|
||||
|
||||
if (ch == ">" && state.tagName) {
|
||||
var tagName = state.tagName;
|
||||
if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch);
|
||||
var lowerTagName = tagName.toLowerCase();
|
||||
// Don't process the '>' at the end of an end-tag or self-closing tag
|
||||
if (tok.type == "tag" && state.type == "closeTag" || tok.string.indexOf("/") > -1 ||
|
||||
dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1)
|
||||
return CodeMirror.Pass;
|
||||
|
||||
var doIndent = indentTags && indexOf(indentTags, lowerTagName) > -1;
|
||||
var curPos = doIndent ? CodeMirror.Pos(pos.line + 1, 0) : CodeMirror.Pos(pos.line, pos.ch + 1);
|
||||
cm.replaceSelection(">" + (doIndent ? "\n\n" : "") + "</" + tagName + ">",
|
||||
{head: curPos, anchor: curPos});
|
||||
if (doIndent) {
|
||||
cm.indentLine(pos.line + 1);
|
||||
cm.indentLine(pos.line + 2);
|
||||
}
|
||||
return;
|
||||
} else if (ch == "/" && tok.string == "<") {
|
||||
var tagName = state.context && state.context.tagName;
|
||||
if (tagName) cm.replaceSelection("/" + tagName + ">", "end");
|
||||
return;
|
||||
}
|
||||
return CodeMirror.Pass;
|
||||
}
|
||||
|
||||
function indexOf(collection, elt) {
|
||||
if (collection.indexOf) return collection.indexOf(elt);
|
||||
for (var i = 0, e = collection.length; i < e; ++i)
|
||||
if (collection[i] == elt) return i;
|
||||
return -1;
|
||||
}
|
||||
})();
|
|
@ -0,0 +1,44 @@
|
|||
(function() {
|
||||
var modes = ["clike", "css", "javascript"];
|
||||
for (var i = 0; i < modes.length; ++i)
|
||||
CodeMirror.extendMode(modes[i], {blockCommentStart: "/*",
|
||||
blockCommentEnd: "*/",
|
||||
blockCommentContinue: " * "});
|
||||
|
||||
function continueComment(cm) {
|
||||
var pos = cm.getCursor(), token = cm.getTokenAt(pos);
|
||||
var mode = CodeMirror.innerMode(cm.getMode(), token.state).mode;
|
||||
var space;
|
||||
|
||||
if (token.type == "comment" && mode.blockCommentStart) {
|
||||
var end = token.string.indexOf(mode.blockCommentEnd);
|
||||
var full = cm.getRange(CodeMirror.Pos(pos.line, 0), CodeMirror.Pos(pos.line, token.end)), found;
|
||||
if (end != -1 && end == token.string.length - mode.blockCommentEnd.length) {
|
||||
// Comment ended, don't continue it
|
||||
} else if (token.string.indexOf(mode.blockCommentStart) == 0) {
|
||||
space = full.slice(0, token.start);
|
||||
if (!/^\s*$/.test(space)) {
|
||||
space = "";
|
||||
for (var i = 0; i < token.start; ++i) space += " ";
|
||||
}
|
||||
} else if ((found = full.indexOf(mode.blockCommentContinue)) != -1 &&
|
||||
found + mode.blockCommentContinue.length > token.start &&
|
||||
/^\s*$/.test(full.slice(0, found))) {
|
||||
space = full.slice(0, found);
|
||||
}
|
||||
}
|
||||
|
||||
if (space != null)
|
||||
cm.replaceSelection("\n" + space + mode.blockCommentContinue, "end");
|
||||
else
|
||||
return CodeMirror.Pass;
|
||||
}
|
||||
|
||||
CodeMirror.defineOption("continueComments", null, function(cm, val, prev) {
|
||||
if (prev && prev != CodeMirror.Init)
|
||||
cm.removeKeyMap("continueComment");
|
||||
var map = {name: "continueComment"};
|
||||
map[typeof val == "string" ? val : "Enter"] = continueComment;
|
||||
cm.addKeyMap(map);
|
||||
});
|
||||
})();
|
|
@ -0,0 +1,25 @@
|
|||
(function() {
|
||||
'use strict';
|
||||
|
||||
var listRE = /^(\s*)([*+-]|(\d+)\.)(\s*)/,
|
||||
unorderedBullets = '*+-';
|
||||
|
||||
CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) {
|
||||
var pos = cm.getCursor(),
|
||||
inList = cm.getStateAfter(pos.line).list,
|
||||
match;
|
||||
|
||||
if (!inList || !(match = cm.getLine(pos.line).match(listRE))) {
|
||||
cm.execCommand('newlineAndIndent');
|
||||
return;
|
||||
}
|
||||
|
||||
var indent = match[1], after = match[4];
|
||||
var bullet = unorderedBullets.indexOf(match[2]) >= 0
|
||||
? match[2]
|
||||
: (parseInt(match[3], 10) + 1) + '.';
|
||||
|
||||
cm.replaceSelection('\n' + indent + bullet + after, 'end');
|
||||
};
|
||||
|
||||
}());
|
|
@ -0,0 +1,74 @@
|
|||
(function() {
|
||||
var ie_lt8 = /MSIE \d/.test(navigator.userAgent) &&
|
||||
(document.documentMode == null || document.documentMode < 8);
|
||||
|
||||
var Pos = CodeMirror.Pos;
|
||||
// Disable brace matching in long lines, since it'll cause hugely slow updates
|
||||
var maxLineLen = 1000;
|
||||
|
||||
var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
|
||||
function findMatchingBracket(cm) {
|
||||
var cur = cm.getCursor(), line = cm.getLineHandle(cur.line), pos = cur.ch - 1;
|
||||
var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];
|
||||
if (!match) return null;
|
||||
var forward = match.charAt(1) == ">", d = forward ? 1 : -1;
|
||||
var style = cm.getTokenAt(Pos(cur.line, pos + 1)).type;
|
||||
|
||||
var stack = [line.text.charAt(pos)], re = /[(){}[\]]/;
|
||||
function scan(line, lineNo, start) {
|
||||
if (!line.text) return;
|
||||
var pos = forward ? 0 : line.text.length - 1, end = forward ? line.text.length : -1;
|
||||
if (start != null) pos = start + d;
|
||||
for (; pos != end; pos += d) {
|
||||
var ch = line.text.charAt(pos);
|
||||
if (re.test(ch) && cm.getTokenAt(Pos(lineNo, pos + 1)).type == style) {
|
||||
var match = matching[ch];
|
||||
if (match.charAt(1) == ">" == forward) stack.push(ch);
|
||||
else if (stack.pop() != match.charAt(0)) return {pos: pos, match: false};
|
||||
else if (!stack.length) return {pos: pos, match: true};
|
||||
}
|
||||
}
|
||||
}
|
||||
for (var i = cur.line, found, e = forward ? Math.min(i + 100, cm.lineCount()) : Math.max(-1, i - 100); i != e; i+=d) {
|
||||
if (i == cur.line) found = scan(line, i, pos);
|
||||
else found = scan(cm.getLineHandle(i), i);
|
||||
if (found) break;
|
||||
}
|
||||
return {from: Pos(cur.line, pos), to: found && Pos(i, found.pos), match: found && found.match};
|
||||
}
|
||||
|
||||
function matchBrackets(cm, autoclear) {
|
||||
var found = findMatchingBracket(cm);
|
||||
if (!found || cm.getLine(found.from.line).length > maxLineLen ||
|
||||
found.to && cm.getLine(found.to.line).length > maxLineLen)
|
||||
return;
|
||||
|
||||
var style = found.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
|
||||
var one = cm.markText(found.from, Pos(found.from.line, found.from.ch + 1), {className: style});
|
||||
var two = found.to && cm.markText(found.to, Pos(found.to.line, found.to.ch + 1), {className: style});
|
||||
// Kludge to work around the IE bug from issue #1193, where text
|
||||
// input stops going to the textare whever this fires.
|
||||
if (ie_lt8 && cm.state.focused) cm.display.input.focus();
|
||||
var clear = function() {
|
||||
cm.operation(function() { one.clear(); two && two.clear(); });
|
||||
};
|
||||
if (autoclear) setTimeout(clear, 800);
|
||||
else return clear;
|
||||
}
|
||||
|
||||
var currentlyHighlighted = null;
|
||||
function doMatchBrackets(cm) {
|
||||
cm.operation(function() {
|
||||
if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}
|
||||
if (!cm.somethingSelected()) currentlyHighlighted = matchBrackets(cm, false);
|
||||
});
|
||||
}
|
||||
|
||||
CodeMirror.defineOption("matchBrackets", false, function(cm, val) {
|
||||
if (val) cm.on("cursorActivity", doMatchBrackets);
|
||||
else cm.off("cursorActivity", doMatchBrackets);
|
||||
});
|
||||
|
||||
CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);});
|
||||
CodeMirror.defineExtension("findMatchingBracket", function(){return findMatchingBracket(this);});
|
||||
})();
|
|
@ -0,0 +1,31 @@
|
|||
CodeMirror.braceRangeFinder = function(cm, start) {
|
||||
var line = start.line, lineText = cm.getLine(line);
|
||||
var at = lineText.length, startChar, tokenType;
|
||||
for (;;) {
|
||||
var found = lineText.lastIndexOf("{", at);
|
||||
if (found < start.ch) break;
|
||||
tokenType = cm.getTokenAt(CodeMirror.Pos(line, found + 1)).type;
|
||||
if (!/^(comment|string)/.test(tokenType)) { startChar = found; break; }
|
||||
at = found - 1;
|
||||
}
|
||||
if (startChar == null || lineText.lastIndexOf("}") > startChar) return;
|
||||
var count = 1, lastLine = cm.lineCount(), end, endCh;
|
||||
outer: for (var i = line + 1; i < lastLine; ++i) {
|
||||
var text = cm.getLine(i), pos = 0;
|
||||
for (;;) {
|
||||
var nextOpen = text.indexOf("{", pos), nextClose = text.indexOf("}", pos);
|
||||
if (nextOpen < 0) nextOpen = text.length;
|
||||
if (nextClose < 0) nextClose = text.length;
|
||||
pos = Math.min(nextOpen, nextClose);
|
||||
if (pos == text.length) break;
|
||||
if (cm.getTokenAt(CodeMirror.Pos(i, pos + 1)).type == tokenType) {
|
||||
if (pos == nextOpen) ++count;
|
||||
else if (!--count) { end = i; endCh = pos; break outer; }
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
if (end == null || end == line + 1) return;
|
||||
return {from: CodeMirror.Pos(line, startChar + 1),
|
||||
to: CodeMirror.Pos(end, endCh)};
|
||||
};
|
|
@ -0,0 +1,32 @@
|
|||
CodeMirror.newFoldFunction = function(rangeFinder, widget) {
|
||||
if (widget == null) widget = "\u2194";
|
||||
if (typeof widget == "string") {
|
||||
var text = document.createTextNode(widget);
|
||||
widget = document.createElement("span");
|
||||
widget.appendChild(text);
|
||||
widget.className = "CodeMirror-foldmarker";
|
||||
}
|
||||
|
||||
return function(cm, pos) {
|
||||
if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0);
|
||||
var range = rangeFinder(cm, pos);
|
||||
if (!range) return;
|
||||
|
||||
var present = cm.findMarksAt(range.from), cleared = 0;
|
||||
for (var i = 0; i < present.length; ++i) {
|
||||
if (present[i].__isFold) {
|
||||
++cleared;
|
||||
present[i].clear();
|
||||
}
|
||||
}
|
||||
if (cleared) return;
|
||||
|
||||
var myWidget = widget.cloneNode(true);
|
||||
CodeMirror.on(myWidget, "mousedown", function() {myRange.clear();});
|
||||
var myRange = cm.markText(range.from, range.to, {
|
||||
replacedWith: myWidget,
|
||||
clearOnEnter: true,
|
||||
__isFold: true
|
||||
});
|
||||
};
|
||||
};
|
|
@ -0,0 +1,64 @@
|
|||
CodeMirror.tagRangeFinder = (function() {
|
||||
var nameStartChar = "A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
|
||||
var nameChar = nameStartChar + "\-\:\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
|
||||
var xmlTagStart = new RegExp("<(/?)([" + nameStartChar + "][" + nameChar + "]*)", "g");
|
||||
|
||||
return function(cm, start) {
|
||||
var line = start.line, ch = start.ch, lineText = cm.getLine(line);
|
||||
|
||||
function nextLine() {
|
||||
if (line >= cm.lastLine()) return;
|
||||
ch = 0;
|
||||
lineText = cm.getLine(++line);
|
||||
return true;
|
||||
}
|
||||
function toTagEnd() {
|
||||
for (;;) {
|
||||
var gt = lineText.indexOf(">", ch);
|
||||
if (gt == -1) { if (nextLine()) continue; else return; }
|
||||
var lastSlash = lineText.lastIndexOf("/", gt);
|
||||
var selfClose = lastSlash > -1 && /^\s*$/.test(lineText.slice(lastSlash + 1, gt));
|
||||
ch = gt + 1;
|
||||
return selfClose ? "selfClose" : "regular";
|
||||
}
|
||||
}
|
||||
function toNextTag() {
|
||||
for (;;) {
|
||||
xmlTagStart.lastIndex = ch;
|
||||
var found = xmlTagStart.exec(lineText);
|
||||
if (!found) { if (nextLine()) continue; else return; }
|
||||
ch = found.index + found[0].length;
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
var stack = [], startCh;
|
||||
for (;;) {
|
||||
var openTag = toNextTag(), end;
|
||||
if (!openTag || line != start.line || !(end = toTagEnd())) return;
|
||||
if (!openTag[1] && end != "selfClose") {
|
||||
stack.push(openTag[2]);
|
||||
startCh = ch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
var next = toNextTag(), end, tagLine = line, tagCh = ch - (next ? next[0].length : 0);
|
||||
if (!next || !(end = toTagEnd())) return;
|
||||
if (end == "selfClose") continue;
|
||||
if (next[1]) { // closing tag
|
||||
for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == next[2]) {
|
||||
stack.length = i;
|
||||
break;
|
||||
}
|
||||
if (!stack.length) return {
|
||||
from: CodeMirror.Pos(start.line, startCh),
|
||||
to: CodeMirror.Pos(tagLine, tagCh)
|
||||
};
|
||||
} else { // opening tag
|
||||
stack.push(next[2]);
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
|
@ -0,0 +1,43 @@
|
|||
(function() {
|
||||
|
||||
// Applies automatic formatting to the specified range
|
||||
CodeMirror.defineExtension("autoFormatAll", function (from, to) {
|
||||
var cm = this;
|
||||
var outer = cm.getMode(), text = cm.getRange(from, to).split("\n");
|
||||
var state = CodeMirror.copyState(outer, cm.getTokenAt(from).state);
|
||||
var tabSize = cm.getOption("tabSize");
|
||||
|
||||
var out = "", lines = 0, atSol = from.ch == 0;
|
||||
function newline() {
|
||||
out += "\n";
|
||||
atSol = true;
|
||||
++lines;
|
||||
}
|
||||
|
||||
for (var i = 0; i < text.length; ++i) {
|
||||
var stream = new CodeMirror.StringStream(text[i], tabSize);
|
||||
while (!stream.eol()) {
|
||||
var inner = CodeMirror.innerMode(outer, state);
|
||||
var style = outer.token(stream, state), cur = stream.current();
|
||||
stream.start = stream.pos;
|
||||
if (!atSol || /\S/.test(cur)) {
|
||||
out += cur;
|
||||
atSol = false;
|
||||
}
|
||||
if (!atSol && inner.mode.newlineAfterToken &&
|
||||
inner.mode.newlineAfterToken(style, cur, stream.string.slice(stream.pos) || text[i+1] || "", inner.state))
|
||||
newline();
|
||||
}
|
||||
if (!stream.pos && outer.blankLine) outer.blankLine(state);
|
||||
if (!atSol && i < text.length - 1) newline();
|
||||
}
|
||||
|
||||
cm.operation(function () {
|
||||
cm.replaceRange(out, from, to);
|
||||
for (var cur = from.line + 1, end = from.line + lines; cur <= end; ++cur)
|
||||
cm.indentLine(cur, "smart");
|
||||
|
||||
cm.setCursor({ line:0, ch:0 });
|
||||
});
|
||||
});
|
||||
})();
|
|
@ -0,0 +1,114 @@
|
|||
(function() {
|
||||
|
||||
CodeMirror.extendMode("css", {
|
||||
commentStart: "/*",
|
||||
commentEnd: "*/",
|
||||
newlineAfterToken: function(_type, content) {
|
||||
return /^[;{}]$/.test(content);
|
||||
}
|
||||
});
|
||||
|
||||
CodeMirror.extendMode("javascript", {
|
||||
commentStart: "/*",
|
||||
commentEnd: "*/",
|
||||
// FIXME semicolons inside of for
|
||||
newlineAfterToken: function(_type, content, textAfter, state) {
|
||||
if (this.jsonMode) {
|
||||
return /^[\[,{]$/.test(content) || /^}/.test(textAfter);
|
||||
} else {
|
||||
if (content == ";" && state.lexical && state.lexical.type == ")") return false;
|
||||
return /^[;{}]$/.test(content) && !/^;/.test(textAfter);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var inlineElements = /^(a|abbr|acronym|area|base|bdo|big|br|button|caption|cite|code|col|colgroup|dd|del|dfn|em|frame|hr|iframe|img|input|ins|kbd|label|legend|link|map|object|optgroup|option|param|q|samp|script|select|small|span|strong|sub|sup|textarea|tt|var)$/;
|
||||
|
||||
CodeMirror.extendMode("xml", {
|
||||
commentStart: "<!--",
|
||||
commentEnd: "-->",
|
||||
newlineAfterToken: function(type, content, textAfter, state) {
|
||||
var inline = false;
|
||||
if (this.configuration == "html")
|
||||
inline = state.context ? inlineElements.test(state.context.tagName) : false;
|
||||
return !inline && ((type == "tag" && />$/.test(content) && state.context) ||
|
||||
/^</.test(textAfter));
|
||||
}
|
||||
});
|
||||
|
||||
// Comment/uncomment the specified range
|
||||
CodeMirror.defineExtension("commentRange", function (isComment, from, to) {
|
||||
var cm = this, curMode = CodeMirror.innerMode(cm.getMode(), cm.getTokenAt(from).state).mode;
|
||||
cm.operation(function() {
|
||||
if (isComment) { // Comment range
|
||||
cm.replaceRange(curMode.commentEnd, to);
|
||||
cm.replaceRange(curMode.commentStart, from);
|
||||
if (from.line == to.line && from.ch == to.ch) // An empty comment inserted - put cursor inside
|
||||
cm.setCursor(from.line, from.ch + curMode.commentStart.length);
|
||||
} else { // Uncomment range
|
||||
var selText = cm.getRange(from, to);
|
||||
var startIndex = selText.indexOf(curMode.commentStart);
|
||||
var endIndex = selText.lastIndexOf(curMode.commentEnd);
|
||||
if (startIndex > -1 && endIndex > -1 && endIndex > startIndex) {
|
||||
// Take string till comment start
|
||||
selText = selText.substr(0, startIndex)
|
||||
// From comment start till comment end
|
||||
+ selText.substring(startIndex + curMode.commentStart.length, endIndex)
|
||||
// From comment end till string end
|
||||
+ selText.substr(endIndex + curMode.commentEnd.length);
|
||||
}
|
||||
cm.replaceRange(selText, from, to);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Applies automatic mode-aware indentation to the specified range
|
||||
CodeMirror.defineExtension("autoIndentRange", function (from, to) {
|
||||
var cmInstance = this;
|
||||
this.operation(function () {
|
||||
for (var i = from.line; i <= to.line; i++) {
|
||||
cmInstance.indentLine(i, "smart");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Applies automatic formatting to the specified range
|
||||
CodeMirror.defineExtension("autoFormatRange", function (from, to) {
|
||||
var cm = this;
|
||||
var outer = cm.getMode(), text = cm.getRange(from, to).split("\n");
|
||||
var state = CodeMirror.copyState(outer, cm.getTokenAt(from).state);
|
||||
var tabSize = cm.getOption("tabSize");
|
||||
|
||||
var out = "", lines = 0, atSol = from.ch == 0;
|
||||
function newline() {
|
||||
out += "\n";
|
||||
atSol = true;
|
||||
++lines;
|
||||
}
|
||||
|
||||
for (var i = 0; i < text.length; ++i) {
|
||||
var stream = new CodeMirror.StringStream(text[i], tabSize);
|
||||
while (!stream.eol()) {
|
||||
var inner = CodeMirror.innerMode(outer, state);
|
||||
var style = outer.token(stream, state), cur = stream.current();
|
||||
stream.start = stream.pos;
|
||||
if (!atSol || /\S/.test(cur)) {
|
||||
out += cur;
|
||||
atSol = false;
|
||||
}
|
||||
if (!atSol && inner.mode.newlineAfterToken &&
|
||||
inner.mode.newlineAfterToken(style, cur, stream.string.slice(stream.pos) || text[i+1] || "", inner.state))
|
||||
newline();
|
||||
}
|
||||
if (!stream.pos && outer.blankLine) outer.blankLine(state);
|
||||
if (!atSol && i < text.length - 1) newline();
|
||||
}
|
||||
|
||||
cm.operation(function () {
|
||||
cm.replaceRange(out, from, to);
|
||||
for (var cur = from.line + 1, end = from.line + lines; cur <= end; ++cur)
|
||||
cm.indentLine(cur, "smart");
|
||||
cm.setSelection(from, cm.getCursor(false));
|
||||
});
|
||||
});
|
||||
})();
|
|
@ -0,0 +1,60 @@
|
|||
// Highlighting text that matches the selection
|
||||
//
|
||||
// Defines an option highlightSelectionMatches, which, when enabled,
|
||||
// will style strings that match the selection throughout the
|
||||
// document.
|
||||
//
|
||||
// The option can be set to true to simply enable it, or to a
|
||||
// {minChars, style} object to explicitly configure it. minChars is
|
||||
// the minimum amount of characters that should be selected for the
|
||||
// behavior to occur, and style is the token style to apply to the
|
||||
// matches. This will be prefixed by "cm-" to create an actual CSS
|
||||
// class name.
|
||||
|
||||
(function() {
|
||||
var DEFAULT_MIN_CHARS = 2;
|
||||
var DEFAULT_TOKEN_STYLE = "matchhighlight";
|
||||
|
||||
function State(options) {
|
||||
this.minChars = typeof options == "object" && options.minChars || DEFAULT_MIN_CHARS;
|
||||
this.style = typeof options == "object" && options.style || DEFAULT_TOKEN_STYLE;
|
||||
this.overlay = null;
|
||||
}
|
||||
|
||||
CodeMirror.defineOption("highlightSelectionMatches", false, function(cm, val, old) {
|
||||
var prev = old && old != CodeMirror.Init;
|
||||
if (val && !prev) {
|
||||
cm._matchHighlightState = new State(val);
|
||||
cm.on("cursorActivity", highlightMatches);
|
||||
} else if (!val && prev) {
|
||||
var over = cm._matchHighlightState.overlay;
|
||||
if (over) cm.removeOverlay(over);
|
||||
cm._matchHighlightState = null;
|
||||
cm.off("cursorActivity", highlightMatches);
|
||||
}
|
||||
});
|
||||
|
||||
function highlightMatches(cm) {
|
||||
cm.operation(function() {
|
||||
var state = cm._matchHighlightState;
|
||||
if (state.overlay) {
|
||||
cm.removeOverlay(state.overlay);
|
||||
state.overlay = null;
|
||||
}
|
||||
|
||||
if (!cm.somethingSelected()) return;
|
||||
var selection = cm.getSelection().replace(/^\s+|\s+$/g, "");
|
||||
if (selection.length < state.minChars) return;
|
||||
|
||||
cm.addOverlay(state.overlay = makeOverlay(selection, state.style));
|
||||
});
|
||||
}
|
||||
|
||||
function makeOverlay(query, style) {
|
||||
return {token: function(stream) {
|
||||
if (stream.match(query)) return style;
|
||||
stream.next();
|
||||
stream.skipTo(query.charAt(0)) || stream.skipToEnd();
|
||||
}};
|
||||
}
|
||||
})();
|
|
@ -0,0 +1,131 @@
|
|||
// Define search commands. Depends on dialog.js or another
|
||||
// implementation of the openDialog method.
|
||||
|
||||
// Replace works a little oddly -- it will do the replace on the next
|
||||
// Ctrl-G (or whatever is bound to findNext) press. You prevent a
|
||||
// replace by making sure the match is no longer selected when hitting
|
||||
// Ctrl-G.
|
||||
|
||||
(function() {
|
||||
function searchOverlay(query) {
|
||||
if (typeof query == "string") return {token: function(stream) {
|
||||
if (stream.match(query)) return "searching";
|
||||
stream.next();
|
||||
stream.skipTo(query.charAt(0)) || stream.skipToEnd();
|
||||
}};
|
||||
return {token: function(stream) {
|
||||
if (stream.match(query)) return "searching";
|
||||
while (!stream.eol()) {
|
||||
stream.next();
|
||||
if (stream.match(query, false)) break;
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
function SearchState() {
|
||||
this.posFrom = this.posTo = this.query = null;
|
||||
this.overlay = null;
|
||||
}
|
||||
function getSearchState(cm) {
|
||||
return cm._searchState || (cm._searchState = new SearchState());
|
||||
}
|
||||
function getSearchCursor(cm, query, pos) {
|
||||
// Heuristic: if the query string is all lowercase, do a case insensitive search.
|
||||
return cm.getSearchCursor(query, pos, typeof query == "string" && query == query.toLowerCase());
|
||||
}
|
||||
function dialog(cm, text, shortText, f) {
|
||||
if (cm.openDialog) cm.openDialog(text, f);
|
||||
else f(prompt(shortText, ""));
|
||||
}
|
||||
function confirmDialog(cm, text, shortText, fs) {
|
||||
if (cm.openConfirm) cm.openConfirm(text, fs);
|
||||
else if (confirm(shortText)) fs[0]();
|
||||
}
|
||||
function parseQuery(query) {
|
||||
var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
|
||||
return isRE ? new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i") : query;
|
||||
}
|
||||
var queryDialog =
|
||||
'Search: <input type="text" style="width: 10em"/> <span style="color: #888">(Use /re/ syntax for regexp search)</span>';
|
||||
function doSearch(cm, rev) {
|
||||
var state = getSearchState(cm);
|
||||
if (state.query) return findNext(cm, rev);
|
||||
dialog(cm, queryDialog, "Search for:", function(query) {
|
||||
cm.operation(function() {
|
||||
if (!query || state.query) return;
|
||||
state.query = parseQuery(query);
|
||||
cm.removeOverlay(state.overlay);
|
||||
state.overlay = searchOverlay(query);
|
||||
cm.addOverlay(state.overlay);
|
||||
state.posFrom = state.posTo = cm.getCursor();
|
||||
findNext(cm, rev);
|
||||
});
|
||||
});
|
||||
}
|
||||
function findNext(cm, rev) {cm.operation(function() {
|
||||
var state = getSearchState(cm);
|
||||
var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo);
|
||||
if (!cursor.find(rev)) {
|
||||
cursor = getSearchCursor(cm, state.query, rev ? CodeMirror.Pos(cm.lastLine()) : CodeMirror.Pos(cm.firstLine(), 0));
|
||||
if (!cursor.find(rev)) return;
|
||||
}
|
||||
cm.setSelection(cursor.from(), cursor.to());
|
||||
state.posFrom = cursor.from(); state.posTo = cursor.to();
|
||||
});}
|
||||
function clearSearch(cm) {cm.operation(function() {
|
||||
var state = getSearchState(cm);
|
||||
if (!state.query) return;
|
||||
state.query = null;
|
||||
cm.removeOverlay(state.overlay);
|
||||
});}
|
||||
|
||||
var replaceQueryDialog =
|
||||
'Replace: <input type="text" style="width: 10em"/> <span style="color: #888">(Use /re/ syntax for regexp search)</span>';
|
||||
var replacementQueryDialog = 'With: <input type="text" style="width: 10em"/>';
|
||||
var doReplaceConfirm = "Replace? <button>Yes</button> <button>No</button> <button>Stop</button>";
|
||||
function replace(cm, all) {
|
||||
dialog(cm, replaceQueryDialog, "Replace:", function(query) {
|
||||
if (!query) return;
|
||||
query = parseQuery(query);
|
||||
dialog(cm, replacementQueryDialog, "Replace with:", function(text) {
|
||||
if (all) {
|
||||
cm.operation(function() {
|
||||
for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
|
||||
if (typeof query != "string") {
|
||||
var match = cm.getRange(cursor.from(), cursor.to()).match(query);
|
||||
cursor.replace(text.replace(/\$(\d)/, function(_, i) {return match[i];}));
|
||||
} else cursor.replace(text);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
clearSearch(cm);
|
||||
var cursor = getSearchCursor(cm, query, cm.getCursor());
|
||||
var advance = function() {
|
||||
var start = cursor.from(), match;
|
||||
if (!(match = cursor.findNext())) {
|
||||
cursor = getSearchCursor(cm, query);
|
||||
if (!(match = cursor.findNext()) ||
|
||||
(start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return;
|
||||
}
|
||||
cm.setSelection(cursor.from(), cursor.to());
|
||||
confirmDialog(cm, doReplaceConfirm, "Replace?",
|
||||
[function() {doReplace(match);}, advance]);
|
||||
};
|
||||
var doReplace = function(match) {
|
||||
cursor.replace(typeof query == "string" ? text :
|
||||
text.replace(/\$(\d)/, function(_, i) {return match[i];}));
|
||||
advance();
|
||||
};
|
||||
advance();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
|
||||
CodeMirror.commands.findNext = doSearch;
|
||||
CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);};
|
||||
CodeMirror.commands.clearSearch = clearSearch;
|
||||
CodeMirror.commands.replace = replace;
|
||||
CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);};
|
||||
})();
|
|
@ -0,0 +1,130 @@
|
|||
(function(){
|
||||
var Pos = CodeMirror.Pos;
|
||||
|
||||
function SearchCursor(cm, query, pos, caseFold) {
|
||||
this.atOccurrence = false; this.cm = cm;
|
||||
if (caseFold == null && typeof query == "string") caseFold = false;
|
||||
|
||||
pos = pos ? cm.clipPos(pos) : Pos(0, 0);
|
||||
this.pos = {from: pos, to: pos};
|
||||
|
||||
// The matches method is filled in based on the type of query.
|
||||
// It takes a position and a direction, and returns an object
|
||||
// describing the next occurrence of the query, or null if no
|
||||
// more matches were found.
|
||||
if (typeof query != "string") { // Regexp match
|
||||
if (!query.global) query = new RegExp(query.source, query.ignoreCase ? "ig" : "g");
|
||||
this.matches = function(reverse, pos) {
|
||||
if (reverse) {
|
||||
query.lastIndex = 0;
|
||||
var line = cm.getLine(pos.line).slice(0, pos.ch), cutOff = 0, match, start;
|
||||
for (;;) {
|
||||
query.lastIndex = cutOff;
|
||||
var newMatch = query.exec(line);
|
||||
if (!newMatch) break;
|
||||
match = newMatch;
|
||||
start = match.index;
|
||||
cutOff = match.index + 1;
|
||||
}
|
||||
} else {
|
||||
query.lastIndex = pos.ch;
|
||||
var line = cm.getLine(pos.line), match = query.exec(line),
|
||||
start = match && match.index;
|
||||
}
|
||||
if (match && match[0])
|
||||
return {from: Pos(pos.line, start),
|
||||
to: Pos(pos.line, start + match[0].length),
|
||||
match: match};
|
||||
};
|
||||
} else { // String query
|
||||
if (caseFold) query = query.toLowerCase();
|
||||
var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;};
|
||||
var target = query.split("\n");
|
||||
// Different methods for single-line and multi-line queries
|
||||
if (target.length == 1) {
|
||||
if (!query.length) {
|
||||
// Empty string would match anything and never progress, so
|
||||
// we define it to match nothing instead.
|
||||
this.matches = function() {};
|
||||
} else {
|
||||
this.matches = function(reverse, pos) {
|
||||
var line = fold(cm.getLine(pos.line)), len = query.length, match;
|
||||
if (reverse ? (pos.ch >= len && (match = line.lastIndexOf(query, pos.ch - len)) != -1)
|
||||
: (match = line.indexOf(query, pos.ch)) != -1)
|
||||
return {from: Pos(pos.line, match),
|
||||
to: Pos(pos.line, match + len)};
|
||||
};
|
||||
}
|
||||
} else {
|
||||
this.matches = function(reverse, pos) {
|
||||
var ln = pos.line, idx = (reverse ? target.length - 1 : 0), match = target[idx], line = fold(cm.getLine(ln));
|
||||
var offsetA = (reverse ? line.indexOf(match) + match.length : line.lastIndexOf(match));
|
||||
if (reverse ? offsetA >= pos.ch || offsetA != match.length
|
||||
: offsetA <= pos.ch || offsetA != line.length - match.length)
|
||||
return;
|
||||
for (;;) {
|
||||
if (reverse ? !ln : ln == cm.lineCount() - 1) return;
|
||||
line = fold(cm.getLine(ln += reverse ? -1 : 1));
|
||||
match = target[reverse ? --idx : ++idx];
|
||||
if (idx > 0 && idx < target.length - 1) {
|
||||
if (line != match) return;
|
||||
else continue;
|
||||
}
|
||||
var offsetB = (reverse ? line.lastIndexOf(match) : line.indexOf(match) + match.length);
|
||||
if (reverse ? offsetB != line.length - match.length : offsetB != match.length)
|
||||
return;
|
||||
var start = Pos(pos.line, offsetA), end = Pos(ln, offsetB);
|
||||
return {from: reverse ? end : start, to: reverse ? start : end};
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SearchCursor.prototype = {
|
||||
findNext: function() {return this.find(false);},
|
||||
findPrevious: function() {return this.find(true);},
|
||||
|
||||
find: function(reverse) {
|
||||
var self = this, pos = this.cm.clipPos(reverse ? this.pos.from : this.pos.to);
|
||||
function savePosAndFail(line) {
|
||||
var pos = Pos(line, 0);
|
||||
self.pos = {from: pos, to: pos};
|
||||
self.atOccurrence = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (this.pos = this.matches(reverse, pos)) {
|
||||
if (!this.pos.from || !this.pos.to) { console.log(this.matches, this.pos); }
|
||||
this.atOccurrence = true;
|
||||
return this.pos.match || true;
|
||||
}
|
||||
if (reverse) {
|
||||
if (!pos.line) return savePosAndFail(0);
|
||||
pos = Pos(pos.line-1, this.cm.getLine(pos.line-1).length);
|
||||
}
|
||||
else {
|
||||
var maxLine = this.cm.lineCount();
|
||||
if (pos.line == maxLine - 1) return savePosAndFail(maxLine);
|
||||
pos = Pos(pos.line + 1, 0);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
from: function() {if (this.atOccurrence) return this.pos.from;},
|
||||
to: function() {if (this.atOccurrence) return this.pos.to;},
|
||||
|
||||
replace: function(newText) {
|
||||
if (!this.atOccurrence) return;
|
||||
var lines = CodeMirror.splitLines(newText);
|
||||
this.cm.replaceRange(lines, this.pos.from, this.pos.to);
|
||||
this.pos.to = Pos(this.pos.from.line + lines.length - 1,
|
||||
lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0));
|
||||
}
|
||||
};
|
||||
|
||||
CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) {
|
||||
return new SearchCursor(this, query, pos, caseFold);
|
||||
});
|
||||
})();
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
1
plugins/redmine_ckeditor/assets/ckeditor-contrib/plugins/codemirror/js/codemirror.min.js
vendored
Normal file
1
plugins/redmine_ckeditor/assets/ckeditor-contrib/plugins/codemirror/js/codemirror.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,567 @@
|
|||
CodeMirror.defineMode("css", function(config) {
|
||||
return CodeMirror.getMode(config, "text/css");
|
||||
});
|
||||
|
||||
CodeMirror.defineMode("css-base", function(config, parserConfig) {
|
||||
"use strict";
|
||||
|
||||
var indentUnit = config.indentUnit,
|
||||
hooks = parserConfig.hooks || {},
|
||||
atMediaTypes = parserConfig.atMediaTypes || {},
|
||||
atMediaFeatures = parserConfig.atMediaFeatures || {},
|
||||
propertyKeywords = parserConfig.propertyKeywords || {},
|
||||
colorKeywords = parserConfig.colorKeywords || {},
|
||||
valueKeywords = parserConfig.valueKeywords || {},
|
||||
allowNested = !!parserConfig.allowNested,
|
||||
type = null;
|
||||
|
||||
function ret(style, tp) { type = tp; return style; }
|
||||
|
||||
function tokenBase(stream, state) {
|
||||
var ch = stream.next();
|
||||
if (hooks[ch]) {
|
||||
// result[0] is style and result[1] is type
|
||||
var result = hooks[ch](stream, state);
|
||||
if (result !== false) return result;
|
||||
}
|
||||
if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("def", stream.current());}
|
||||
else if (ch == "=") ret(null, "compare");
|
||||
else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
|
||||
else if (ch == "\"" || ch == "'") {
|
||||
state.tokenize = tokenString(ch);
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
else if (ch == "#") {
|
||||
stream.eatWhile(/[\w\\\-]/);
|
||||
return ret("atom", "hash");
|
||||
}
|
||||
else if (ch == "!") {
|
||||
stream.match(/^\s*\w*/);
|
||||
return ret("keyword", "important");
|
||||
}
|
||||
else if (/\d/.test(ch)) {
|
||||
stream.eatWhile(/[\w.%]/);
|
||||
return ret("number", "unit");
|
||||
}
|
||||
else if (ch === "-") {
|
||||
if (/\d/.test(stream.peek())) {
|
||||
stream.eatWhile(/[\w.%]/);
|
||||
return ret("number", "unit");
|
||||
} else if (stream.match(/^[^-]+-/)) {
|
||||
return ret("meta", "meta");
|
||||
}
|
||||
}
|
||||
else if (/[,+>*\/]/.test(ch)) {
|
||||
return ret(null, "select-op");
|
||||
}
|
||||
else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
|
||||
return ret("qualifier", "qualifier");
|
||||
}
|
||||
else if (ch == ":") {
|
||||
return ret("operator", ch);
|
||||
}
|
||||
else if (/[;{}\[\]\(\)]/.test(ch)) {
|
||||
return ret(null, ch);
|
||||
}
|
||||
else if (ch == "u" && stream.match("rl(")) {
|
||||
stream.backUp(1);
|
||||
state.tokenize = tokenParenthesized;
|
||||
return ret("property", "variable");
|
||||
}
|
||||
else {
|
||||
stream.eatWhile(/[\w\\\-]/);
|
||||
return ret("property", "variable");
|
||||
}
|
||||
}
|
||||
|
||||
function tokenString(quote, nonInclusive) {
|
||||
return function(stream, state) {
|
||||
var escaped = false, ch;
|
||||
while ((ch = stream.next()) != null) {
|
||||
if (ch == quote && !escaped)
|
||||
break;
|
||||
escaped = !escaped && ch == "\\";
|
||||
}
|
||||
if (!escaped) {
|
||||
if (nonInclusive) stream.backUp(1);
|
||||
state.tokenize = tokenBase;
|
||||
}
|
||||
return ret("string", "string");
|
||||
};
|
||||
}
|
||||
|
||||
function tokenParenthesized(stream, state) {
|
||||
stream.next(); // Must be '('
|
||||
if (!stream.match(/\s*[\"\']/, false))
|
||||
state.tokenize = tokenString(")", true);
|
||||
else
|
||||
state.tokenize = tokenBase;
|
||||
return ret(null, "(");
|
||||
}
|
||||
|
||||
return {
|
||||
startState: function(base) {
|
||||
return {tokenize: tokenBase,
|
||||
baseIndent: base || 0,
|
||||
stack: []};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
|
||||
// Use these terms when applicable (see http://www.xanthir.com/blog/b4E50)
|
||||
//
|
||||
// rule** or **ruleset:
|
||||
// A selector + braces combo, or an at-rule.
|
||||
//
|
||||
// declaration block:
|
||||
// A sequence of declarations.
|
||||
//
|
||||
// declaration:
|
||||
// A property + colon + value combo.
|
||||
//
|
||||
// property value:
|
||||
// The entire value of a property.
|
||||
//
|
||||
// component value:
|
||||
// A single piece of a property value. Like the 5px in
|
||||
// text-shadow: 0 0 5px blue;. Can also refer to things that are
|
||||
// multiple terms, like the 1-4 terms that make up the background-size
|
||||
// portion of the background shorthand.
|
||||
//
|
||||
// term:
|
||||
// The basic unit of author-facing CSS, like a single number (5),
|
||||
// dimension (5px), string ("foo"), or function. Officially defined
|
||||
// by the CSS 2.1 grammar (look for the 'term' production)
|
||||
//
|
||||
//
|
||||
// simple selector:
|
||||
// A single atomic selector, like a type selector, an attr selector, a
|
||||
// class selector, etc.
|
||||
//
|
||||
// compound selector:
|
||||
// One or more simple selectors without a combinator. div.example is
|
||||
// compound, div > .example is not.
|
||||
//
|
||||
// complex selector:
|
||||
// One or more compound selectors chained with combinators.
|
||||
//
|
||||
// combinator:
|
||||
// The parts of selectors that express relationships. There are four
|
||||
// currently - the space (descendant combinator), the greater-than
|
||||
// bracket (child combinator), the plus sign (next sibling combinator),
|
||||
// and the tilda (following sibling combinator).
|
||||
//
|
||||
// sequence of selectors:
|
||||
// One or more of the named type of selector chained with commas.
|
||||
|
||||
state.tokenize = state.tokenize || tokenBase;
|
||||
if (state.tokenize == tokenBase && stream.eatSpace()) return null;
|
||||
var style = state.tokenize(stream, state);
|
||||
if (style && typeof style != "string") style = ret(style[0], style[1]);
|
||||
|
||||
// Changing style returned based on context
|
||||
var context = state.stack[state.stack.length-1];
|
||||
if (style == "variable") {
|
||||
if (type == "variable-definition") state.stack.push("propertyValue");
|
||||
return "variable-2";
|
||||
} else if (style == "property") {
|
||||
if (context == "propertyValue"){
|
||||
if (valueKeywords[stream.current()]) {
|
||||
style = "string-2";
|
||||
} else if (colorKeywords[stream.current()]) {
|
||||
style = "keyword";
|
||||
} else {
|
||||
style = "variable-2";
|
||||
}
|
||||
} else if (context == "rule") {
|
||||
if (!propertyKeywords[stream.current()]) {
|
||||
style += " error";
|
||||
}
|
||||
} else if (context == "block") {
|
||||
// if a value is present in both property, value, or color, the order
|
||||
// of preference is property -> color -> value
|
||||
if (propertyKeywords[stream.current()]) {
|
||||
style = "property";
|
||||
} else if (colorKeywords[stream.current()]) {
|
||||
style = "keyword";
|
||||
} else if (valueKeywords[stream.current()]) {
|
||||
style = "string-2";
|
||||
} else {
|
||||
style = "tag";
|
||||
}
|
||||
} else if (!context || context == "@media{") {
|
||||
style = "tag";
|
||||
} else if (context == "@media") {
|
||||
if (atMediaTypes[stream.current()]) {
|
||||
style = "attribute"; // Known attribute
|
||||
} else if (/^(only|not)$/i.test(stream.current())) {
|
||||
style = "keyword";
|
||||
} else if (stream.current().toLowerCase() == "and") {
|
||||
style = "error"; // "and" is only allowed in @mediaType
|
||||
} else if (atMediaFeatures[stream.current()]) {
|
||||
style = "error"; // Known property, should be in @mediaType(
|
||||
} else {
|
||||
// Unknown, expecting keyword or attribute, assuming attribute
|
||||
style = "attribute error";
|
||||
}
|
||||
} else if (context == "@mediaType") {
|
||||
if (atMediaTypes[stream.current()]) {
|
||||
style = "attribute";
|
||||
} else if (stream.current().toLowerCase() == "and") {
|
||||
style = "operator";
|
||||
} else if (/^(only|not)$/i.test(stream.current())) {
|
||||
style = "error"; // Only allowed in @media
|
||||
} else if (atMediaFeatures[stream.current()]) {
|
||||
style = "error"; // Known property, should be in parentheses
|
||||
} else {
|
||||
// Unknown attribute or property, but expecting property (preceded
|
||||
// by "and"). Should be in parentheses
|
||||
style = "error";
|
||||
}
|
||||
} else if (context == "@mediaType(") {
|
||||
if (propertyKeywords[stream.current()]) {
|
||||
// do nothing, remains "property"
|
||||
} else if (atMediaTypes[stream.current()]) {
|
||||
style = "error"; // Known property, should be in parentheses
|
||||
} else if (stream.current().toLowerCase() == "and") {
|
||||
style = "operator";
|
||||
} else if (/^(only|not)$/i.test(stream.current())) {
|
||||
style = "error"; // Only allowed in @media
|
||||
} else {
|
||||
style += " error";
|
||||
}
|
||||
} else {
|
||||
style = "error";
|
||||
}
|
||||
} else if (style == "atom") {
|
||||
if(!context || context == "@media{" || context == "block") {
|
||||
style = "builtin";
|
||||
} else if (context == "propertyValue") {
|
||||
if (!/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) {
|
||||
style += " error";
|
||||
}
|
||||
} else {
|
||||
style = "error";
|
||||
}
|
||||
} else if (context == "@media" && type == "{") {
|
||||
style = "error";
|
||||
}
|
||||
|
||||
// Push/pop context stack
|
||||
if (type == "{") {
|
||||
if (context == "@media" || context == "@mediaType") {
|
||||
state.stack.pop();
|
||||
state.stack[state.stack.length-1] = "@media{";
|
||||
}
|
||||
else {
|
||||
var newContext = allowNested ? "block" : "rule";
|
||||
state.stack.push(newContext);
|
||||
}
|
||||
}
|
||||
else if (type == "}") {
|
||||
var lastState = state.stack[state.stack.length - 1];
|
||||
if (lastState == "interpolation") style = "operator";
|
||||
state.stack.pop();
|
||||
if (context == "propertyValue") state.stack.pop();
|
||||
}
|
||||
else if (type == "interpolation") state.stack.push("interpolation");
|
||||
else if (type == "@media") state.stack.push("@media");
|
||||
else if (context == "@media" && /\b(keyword|attribute)\b/.test(style))
|
||||
state.stack.push("@mediaType");
|
||||
else if (context == "@mediaType" && stream.current() == ",") state.stack.pop();
|
||||
else if (context == "@mediaType" && type == "(") state.stack.push("@mediaType(");
|
||||
else if (context == "@mediaType(" && type == ")") state.stack.pop();
|
||||
else if ((context == "rule" || context == "block") && type == ":") state.stack.push("propertyValue");
|
||||
else if (context == "propertyValue" && type == ";") state.stack.pop();
|
||||
return style;
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
var n = state.stack.length;
|
||||
if (/^\}/.test(textAfter))
|
||||
n -= state.stack[state.stack.length-1] == "propertyValue" ? 2 : 1;
|
||||
return state.baseIndent + n * indentUnit;
|
||||
},
|
||||
|
||||
electricChars: "}"
|
||||
};
|
||||
});
|
||||
|
||||
(function() {
|
||||
function keySet(array) {
|
||||
var keys = {};
|
||||
for (var i = 0; i < array.length; ++i) {
|
||||
keys[array[i]] = true;
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
var atMediaTypes = keySet([
|
||||
"all", "aural", "braille", "handheld", "print", "projection", "screen",
|
||||
"tty", "tv", "embossed"
|
||||
]);
|
||||
|
||||
var atMediaFeatures = keySet([
|
||||
"width", "min-width", "max-width", "height", "min-height", "max-height",
|
||||
"device-width", "min-device-width", "max-device-width", "device-height",
|
||||
"min-device-height", "max-device-height", "aspect-ratio",
|
||||
"min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
|
||||
"min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
|
||||
"max-color", "color-index", "min-color-index", "max-color-index",
|
||||
"monochrome", "min-monochrome", "max-monochrome", "resolution",
|
||||
"min-resolution", "max-resolution", "scan", "grid"
|
||||
]);
|
||||
|
||||
var propertyKeywords = keySet([
|
||||
"align-content", "align-items", "align-self", "alignment-adjust",
|
||||
"alignment-baseline", "anchor-point", "animation", "animation-delay",
|
||||
"animation-direction", "animation-duration", "animation-iteration-count",
|
||||
"animation-name", "animation-play-state", "animation-timing-function",
|
||||
"appearance", "azimuth", "backface-visibility", "background",
|
||||
"background-attachment", "background-clip", "background-color",
|
||||
"background-image", "background-origin", "background-position",
|
||||
"background-repeat", "background-size", "baseline-shift", "binding",
|
||||
"bleed", "bookmark-label", "bookmark-level", "bookmark-state",
|
||||
"bookmark-target", "border", "border-bottom", "border-bottom-color",
|
||||
"border-bottom-left-radius", "border-bottom-right-radius",
|
||||
"border-bottom-style", "border-bottom-width", "border-collapse",
|
||||
"border-color", "border-image", "border-image-outset",
|
||||
"border-image-repeat", "border-image-slice", "border-image-source",
|
||||
"border-image-width", "border-left", "border-left-color",
|
||||
"border-left-style", "border-left-width", "border-radius", "border-right",
|
||||
"border-right-color", "border-right-style", "border-right-width",
|
||||
"border-spacing", "border-style", "border-top", "border-top-color",
|
||||
"border-top-left-radius", "border-top-right-radius", "border-top-style",
|
||||
"border-top-width", "border-width", "bottom", "box-decoration-break",
|
||||
"box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
|
||||
"caption-side", "clear", "clip", "color", "color-profile", "column-count",
|
||||
"column-fill", "column-gap", "column-rule", "column-rule-color",
|
||||
"column-rule-style", "column-rule-width", "column-span", "column-width",
|
||||
"columns", "content", "counter-increment", "counter-reset", "crop", "cue",
|
||||
"cue-after", "cue-before", "cursor", "direction", "display",
|
||||
"dominant-baseline", "drop-initial-after-adjust",
|
||||
"drop-initial-after-align", "drop-initial-before-adjust",
|
||||
"drop-initial-before-align", "drop-initial-size", "drop-initial-value",
|
||||
"elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
|
||||
"flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
|
||||
"float", "float-offset", "font", "font-feature-settings", "font-family",
|
||||
"font-kerning", "font-language-override", "font-size", "font-size-adjust",
|
||||
"font-stretch", "font-style", "font-synthesis", "font-variant",
|
||||
"font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
|
||||
"font-variant-ligatures", "font-variant-numeric", "font-variant-position",
|
||||
"font-weight", "grid-cell", "grid-column", "grid-column-align",
|
||||
"grid-column-sizing", "grid-column-span", "grid-columns", "grid-flow",
|
||||
"grid-row", "grid-row-align", "grid-row-sizing", "grid-row-span",
|
||||
"grid-rows", "grid-template", "hanging-punctuation", "height", "hyphens",
|
||||
"icon", "image-orientation", "image-rendering", "image-resolution",
|
||||
"inline-box-align", "justify-content", "left", "letter-spacing",
|
||||
"line-break", "line-height", "line-stacking", "line-stacking-ruby",
|
||||
"line-stacking-shift", "line-stacking-strategy", "list-style",
|
||||
"list-style-image", "list-style-position", "list-style-type", "margin",
|
||||
"margin-bottom", "margin-left", "margin-right", "margin-top",
|
||||
"marker-offset", "marks", "marquee-direction", "marquee-loop",
|
||||
"marquee-play-count", "marquee-speed", "marquee-style", "max-height",
|
||||
"max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
|
||||
"nav-left", "nav-right", "nav-up", "opacity", "order", "orphans", "outline",
|
||||
"outline-color", "outline-offset", "outline-style", "outline-width",
|
||||
"overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
|
||||
"padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
|
||||
"page", "page-break-after", "page-break-before", "page-break-inside",
|
||||
"page-policy", "pause", "pause-after", "pause-before", "perspective",
|
||||
"perspective-origin", "pitch", "pitch-range", "play-during", "position",
|
||||
"presentation-level", "punctuation-trim", "quotes", "rendering-intent",
|
||||
"resize", "rest", "rest-after", "rest-before", "richness", "right",
|
||||
"rotation", "rotation-point", "ruby-align", "ruby-overhang",
|
||||
"ruby-position", "ruby-span", "size", "speak", "speak-as", "speak-header",
|
||||
"speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
|
||||
"tab-size", "table-layout", "target", "target-name", "target-new",
|
||||
"target-position", "text-align", "text-align-last", "text-decoration",
|
||||
"text-decoration-color", "text-decoration-line", "text-decoration-skip",
|
||||
"text-decoration-style", "text-emphasis", "text-emphasis-color",
|
||||
"text-emphasis-position", "text-emphasis-style", "text-height",
|
||||
"text-indent", "text-justify", "text-outline", "text-shadow",
|
||||
"text-space-collapse", "text-transform", "text-underline-position",
|
||||
"text-wrap", "top", "transform", "transform-origin", "transform-style",
|
||||
"transition", "transition-delay", "transition-duration",
|
||||
"transition-property", "transition-timing-function", "unicode-bidi",
|
||||
"vertical-align", "visibility", "voice-balance", "voice-duration",
|
||||
"voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
|
||||
"voice-volume", "volume", "white-space", "widows", "width", "word-break",
|
||||
"word-spacing", "word-wrap", "z-index"
|
||||
]);
|
||||
|
||||
var colorKeywords = keySet([
|
||||
"black", "silver", "gray", "white", "maroon", "red", "purple", "fuchsia",
|
||||
"green", "lime", "olive", "yellow", "navy", "blue", "teal", "aqua"
|
||||
]);
|
||||
|
||||
var valueKeywords = keySet([
|
||||
"above", "absolute", "activeborder", "activecaption", "afar",
|
||||
"after-white-space", "ahead", "alias", "all", "all-scroll", "alternate",
|
||||
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
|
||||
"arabic-indic", "armenian", "asterisks", "auto", "avoid", "background",
|
||||
"backwards", "baseline", "below", "bidi-override", "binary", "bengali",
|
||||
"blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
|
||||
"both", "bottom", "break-all", "break-word", "button", "button-bevel",
|
||||
"buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian",
|
||||
"capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
|
||||
"cell", "center", "checkbox", "circle", "cjk-earthly-branch",
|
||||
"cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
|
||||
"col-resize", "collapse", "compact", "condensed", "contain", "content",
|
||||
"content-box", "context-menu", "continuous", "copy", "cover", "crop",
|
||||
"cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal",
|
||||
"decimal-leading-zero", "default", "default-button", "destination-atop",
|
||||
"destination-in", "destination-out", "destination-over", "devanagari",
|
||||
"disc", "discard", "document", "dot-dash", "dot-dot-dash", "dotted",
|
||||
"double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
|
||||
"element", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
|
||||
"ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
|
||||
"ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
|
||||
"ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
|
||||
"ethiopic-halehame-gez", "ethiopic-halehame-om-et",
|
||||
"ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
|
||||
"ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et",
|
||||
"ethiopic-halehame-tig", "ew-resize", "expanded", "extra-condensed",
|
||||
"extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes",
|
||||
"forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
|
||||
"gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew",
|
||||
"help", "hidden", "hide", "higher", "highlight", "highlighttext",
|
||||
"hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
|
||||
"inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
|
||||
"infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
|
||||
"inline-block", "inline-table", "inset", "inside", "intrinsic", "invert",
|
||||
"italic", "justify", "kannada", "katakana", "katakana-iroha", "khmer",
|
||||
"landscape", "lao", "large", "larger", "left", "level", "lighter",
|
||||
"line-through", "linear", "lines", "list-item", "listbox", "listitem",
|
||||
"local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
|
||||
"lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
|
||||
"lower-roman", "lowercase", "ltr", "malayalam", "match",
|
||||
"media-controls-background", "media-current-time-display",
|
||||
"media-fullscreen-button", "media-mute-button", "media-play-button",
|
||||
"media-return-to-realtime-button", "media-rewind-button",
|
||||
"media-seek-back-button", "media-seek-forward-button", "media-slider",
|
||||
"media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
|
||||
"media-volume-slider-container", "media-volume-sliderthumb", "medium",
|
||||
"menu", "menulist", "menulist-button", "menulist-text",
|
||||
"menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
|
||||
"mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize",
|
||||
"narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
|
||||
"no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
|
||||
"ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
|
||||
"optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
|
||||
"outside", "overlay", "overline", "padding", "padding-box", "painted",
|
||||
"paused", "persian", "plus-darker", "plus-lighter", "pointer", "portrait",
|
||||
"pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button",
|
||||
"radio", "read-only", "read-write", "read-write-plaintext-only", "relative",
|
||||
"repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba",
|
||||
"ridge", "right", "round", "row-resize", "rtl", "run-in", "running",
|
||||
"s-resize", "sans-serif", "scroll", "scrollbar", "se-resize", "searchfield",
|
||||
"searchfield-cancel-button", "searchfield-decoration",
|
||||
"searchfield-results-button", "searchfield-results-decoration",
|
||||
"semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
|
||||
"single", "skip-white-space", "slide", "slider-horizontal",
|
||||
"slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
|
||||
"small", "small-caps", "small-caption", "smaller", "solid", "somali",
|
||||
"source-atop", "source-in", "source-out", "source-over", "space", "square",
|
||||
"square-button", "start", "static", "status-bar", "stretch", "stroke",
|
||||
"sub", "subpixel-antialiased", "super", "sw-resize", "table",
|
||||
"table-caption", "table-cell", "table-column", "table-column-group",
|
||||
"table-footer-group", "table-header-group", "table-row", "table-row-group",
|
||||
"telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
|
||||
"thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
|
||||
"threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
|
||||
"tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
|
||||
"transparent", "ultra-condensed", "ultra-expanded", "underline", "up",
|
||||
"upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
|
||||
"upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
|
||||
"vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
|
||||
"visibleStroke", "visual", "w-resize", "wait", "wave", "white", "wider",
|
||||
"window", "windowframe", "windowtext", "x-large", "x-small", "xor",
|
||||
"xx-large", "xx-small"
|
||||
]);
|
||||
|
||||
function tokenCComment(stream, state) {
|
||||
var maybeEnd = false, ch;
|
||||
while ((ch = stream.next()) != null) {
|
||||
if (maybeEnd && ch == "/") {
|
||||
state.tokenize = null;
|
||||
break;
|
||||
}
|
||||
maybeEnd = (ch == "*");
|
||||
}
|
||||
return ["comment", "comment"];
|
||||
}
|
||||
|
||||
CodeMirror.defineMIME("text/css", {
|
||||
atMediaTypes: atMediaTypes,
|
||||
atMediaFeatures: atMediaFeatures,
|
||||
propertyKeywords: propertyKeywords,
|
||||
colorKeywords: colorKeywords,
|
||||
valueKeywords: valueKeywords,
|
||||
hooks: {
|
||||
"<": function(stream, state) {
|
||||
function tokenSGMLComment(stream, state) {
|
||||
var dashes = 0, ch;
|
||||
while ((ch = stream.next()) != null) {
|
||||
if (dashes >= 2 && ch == ">") {
|
||||
state.tokenize = null;
|
||||
break;
|
||||
}
|
||||
dashes = (ch == "-") ? dashes + 1 : 0;
|
||||
}
|
||||
return ["comment", "comment"];
|
||||
}
|
||||
if (stream.eat("!")) {
|
||||
state.tokenize = tokenSGMLComment;
|
||||
return tokenSGMLComment(stream, state);
|
||||
}
|
||||
},
|
||||
"/": function(stream, state) {
|
||||
if (stream.eat("*")) {
|
||||
state.tokenize = tokenCComment;
|
||||
return tokenCComment(stream, state);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
name: "css-base"
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-scss", {
|
||||
atMediaTypes: atMediaTypes,
|
||||
atMediaFeatures: atMediaFeatures,
|
||||
propertyKeywords: propertyKeywords,
|
||||
colorKeywords: colorKeywords,
|
||||
valueKeywords: valueKeywords,
|
||||
allowNested: true,
|
||||
hooks: {
|
||||
"$": function(stream) {
|
||||
stream.match(/^[\w-]+/);
|
||||
if (stream.peek() == ":") {
|
||||
return ["variable", "variable-definition"];
|
||||
}
|
||||
return ["variable", "variable"];
|
||||
},
|
||||
"/": function(stream, state) {
|
||||
if (stream.eat("/")) {
|
||||
stream.skipToEnd();
|
||||
return ["comment", "comment"];
|
||||
} else if (stream.eat("*")) {
|
||||
state.tokenize = tokenCComment;
|
||||
return tokenCComment(stream, state);
|
||||
} else {
|
||||
return ["operator", "operator"];
|
||||
}
|
||||
},
|
||||
"#": function(stream) {
|
||||
if (stream.eat("{")) {
|
||||
return ["operator", "interpolation"];
|
||||
} else {
|
||||
stream.eatWhile(/[\w\\\-]/);
|
||||
return ["atom", "hash"];
|
||||
}
|
||||
}
|
||||
},
|
||||
name: "css-base"
|
||||
});
|
||||
})();
|
|
@ -0,0 +1,104 @@
|
|||
CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
|
||||
var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true});
|
||||
var cssMode = CodeMirror.getMode(config, "css");
|
||||
|
||||
var scriptTypes = [], scriptTypesConf = parserConfig && parserConfig.scriptTypes;
|
||||
scriptTypes.push({matches: /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i,
|
||||
mode: CodeMirror.getMode(config, "javascript")});
|
||||
if (scriptTypesConf) for (var i = 0; i < scriptTypesConf.length; ++i) {
|
||||
var conf = scriptTypesConf[i];
|
||||
scriptTypes.push({matches: conf.matches, mode: conf.mode && CodeMirror.getMode(config, conf.mode)});
|
||||
}
|
||||
scriptTypes.push({matches: /./,
|
||||
mode: CodeMirror.getMode(config, "text/plain")});
|
||||
|
||||
function html(stream, state) {
|
||||
var tagName = state.htmlState.tagName;
|
||||
var style = htmlMode.token(stream, state.htmlState);
|
||||
if (tagName == "script" && /\btag\b/.test(style) && stream.current() == ">") {
|
||||
// Script block: mode to change to depends on type attribute
|
||||
var scriptType = stream.string.slice(Math.max(0, stream.pos - 100), stream.pos).match(/\btype\s*=\s*("[^"]+"|'[^']+'|\S+)[^<]*$/i);
|
||||
scriptType = scriptType ? scriptType[1] : "";
|
||||
if (scriptType && /[\"\']/.test(scriptType.charAt(0))) scriptType = scriptType.slice(1, scriptType.length - 1);
|
||||
for (var i = 0; i < scriptTypes.length; ++i) {
|
||||
var tp = scriptTypes[i];
|
||||
if (typeof tp.matches == "string" ? scriptType == tp.matches : tp.matches.test(scriptType)) {
|
||||
if (tp.mode) {
|
||||
state.token = script;
|
||||
state.localMode = tp.mode;
|
||||
state.localState = tp.mode.startState && tp.mode.startState(htmlMode.indent(state.htmlState, ""));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (tagName == "style" && /\btag\b/.test(style) && stream.current() == ">") {
|
||||
state.token = css;
|
||||
state.localMode = cssMode;
|
||||
state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
|
||||
}
|
||||
return style;
|
||||
}
|
||||
function maybeBackup(stream, pat, style) {
|
||||
var cur = stream.current();
|
||||
var close = cur.search(pat), m;
|
||||
if (close > -1) stream.backUp(cur.length - close);
|
||||
else if (m = cur.match(/<\/?$/)) {
|
||||
stream.backUp(cur.length);
|
||||
if (!stream.match(pat, false)) stream.match(cur[0]);
|
||||
}
|
||||
return style;
|
||||
}
|
||||
function script(stream, state) {
|
||||
if (stream.match(/^<\/\s*script\s*>/i, false)) {
|
||||
state.token = html;
|
||||
state.localState = state.localMode = null;
|
||||
return html(stream, state);
|
||||
}
|
||||
return maybeBackup(stream, /<\/\s*script\s*>/,
|
||||
state.localMode.token(stream, state.localState));
|
||||
}
|
||||
function css(stream, state) {
|
||||
if (stream.match(/^<\/\s*style\s*>/i, false)) {
|
||||
state.token = html;
|
||||
state.localState = state.localMode = null;
|
||||
return html(stream, state);
|
||||
}
|
||||
return maybeBackup(stream, /<\/\s*style\s*>/,
|
||||
cssMode.token(stream, state.localState));
|
||||
}
|
||||
|
||||
return {
|
||||
startState: function() {
|
||||
var state = htmlMode.startState();
|
||||
return {token: html, localMode: null, localState: null, htmlState: state};
|
||||
},
|
||||
|
||||
copyState: function(state) {
|
||||
if (state.localState)
|
||||
var local = CodeMirror.copyState(state.localMode, state.localState);
|
||||
return {token: state.token, localMode: state.localMode, localState: local,
|
||||
htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
return state.token(stream, state);
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
if (!state.localMode || /^\s*<\//.test(textAfter))
|
||||
return htmlMode.indent(state.htmlState, textAfter);
|
||||
else if (state.localMode.indent)
|
||||
return state.localMode.indent(state.localState, textAfter);
|
||||
else
|
||||
return CodeMirror.Pass;
|
||||
},
|
||||
|
||||
electricChars: "/{}:",
|
||||
|
||||
innerMode: function(state) {
|
||||
return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
|
||||
}
|
||||
};
|
||||
}, "xml", "javascript", "css");
|
||||
|
||||
CodeMirror.defineMIME("text/html", "htmlmixed");
|
|
@ -0,0 +1,437 @@
|
|||
// TODO actually recognize syntax of TypeScript constructs
|
||||
|
||||
CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
var indentUnit = config.indentUnit;
|
||||
var jsonMode = parserConfig.json;
|
||||
var isTS = parserConfig.typescript;
|
||||
|
||||
// Tokenizer
|
||||
|
||||
var keywords = function(){
|
||||
function kw(type) {return {type: type, style: "keyword"};}
|
||||
var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
|
||||
var operator = kw("operator"), atom = {type: "atom", style: "atom"};
|
||||
|
||||
var jsKeywords = {
|
||||
"if": A, "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
|
||||
"return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C,
|
||||
"var": kw("var"), "const": kw("var"), "let": kw("var"),
|
||||
"function": kw("function"), "catch": kw("catch"),
|
||||
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
|
||||
"in": operator, "typeof": operator, "instanceof": operator,
|
||||
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
|
||||
"this": kw("this")
|
||||
};
|
||||
|
||||
// Extend the 'normal' keywords with the TypeScript language extensions
|
||||
if (isTS) {
|
||||
var type = {type: "variable", style: "variable-3"};
|
||||
var tsKeywords = {
|
||||
// object-like things
|
||||
"interface": kw("interface"),
|
||||
"class": kw("class"),
|
||||
"extends": kw("extends"),
|
||||
"constructor": kw("constructor"),
|
||||
|
||||
// scope modifiers
|
||||
"public": kw("public"),
|
||||
"private": kw("private"),
|
||||
"protected": kw("protected"),
|
||||
"static": kw("static"),
|
||||
|
||||
"super": kw("super"),
|
||||
|
||||
// types
|
||||
"string": type, "number": type, "bool": type, "any": type
|
||||
};
|
||||
|
||||
for (var attr in tsKeywords) {
|
||||
jsKeywords[attr] = tsKeywords[attr];
|
||||
}
|
||||
}
|
||||
|
||||
return jsKeywords;
|
||||
}();
|
||||
|
||||
var isOperatorChar = /[+\-*&%=<>!?|~^]/;
|
||||
|
||||
function chain(stream, state, f) {
|
||||
state.tokenize = f;
|
||||
return f(stream, state);
|
||||
}
|
||||
|
||||
function nextUntilUnescaped(stream, end) {
|
||||
var escaped = false, next;
|
||||
while ((next = stream.next()) != null) {
|
||||
if (next == end && !escaped)
|
||||
return false;
|
||||
escaped = !escaped && next == "\\";
|
||||
}
|
||||
return escaped;
|
||||
}
|
||||
|
||||
// Used as scratch variables to communicate multiple values without
|
||||
// consing up tons of objects.
|
||||
var type, content;
|
||||
function ret(tp, style, cont) {
|
||||
type = tp; content = cont;
|
||||
return style;
|
||||
}
|
||||
|
||||
function jsTokenBase(stream, state) {
|
||||
var ch = stream.next();
|
||||
if (ch == '"' || ch == "'")
|
||||
return chain(stream, state, jsTokenString(ch));
|
||||
else if (/[\[\]{}\(\),;\:\.]/.test(ch))
|
||||
return ret(ch);
|
||||
else if (ch == "0" && stream.eat(/x/i)) {
|
||||
stream.eatWhile(/[\da-f]/i);
|
||||
return ret("number", "number");
|
||||
}
|
||||
else if (/\d/.test(ch) || ch == "-" && stream.eat(/\d/)) {
|
||||
stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
|
||||
return ret("number", "number");
|
||||
}
|
||||
else if (ch == "/") {
|
||||
if (stream.eat("*")) {
|
||||
return chain(stream, state, jsTokenComment);
|
||||
}
|
||||
else if (stream.eat("/")) {
|
||||
stream.skipToEnd();
|
||||
return ret("comment", "comment");
|
||||
}
|
||||
else if (state.lastType == "operator" || state.lastType == "keyword c" ||
|
||||
/^[\[{}\(,;:]$/.test(state.lastType)) {
|
||||
nextUntilUnescaped(stream, "/");
|
||||
stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
|
||||
return ret("regexp", "string-2");
|
||||
}
|
||||
else {
|
||||
stream.eatWhile(isOperatorChar);
|
||||
return ret("operator", null, stream.current());
|
||||
}
|
||||
}
|
||||
else if (ch == "#") {
|
||||
stream.skipToEnd();
|
||||
return ret("error", "error");
|
||||
}
|
||||
else if (isOperatorChar.test(ch)) {
|
||||
stream.eatWhile(isOperatorChar);
|
||||
return ret("operator", null, stream.current());
|
||||
}
|
||||
else {
|
||||
stream.eatWhile(/[\w\$_]/);
|
||||
var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
|
||||
return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
|
||||
ret("variable", "variable", word);
|
||||
}
|
||||
}
|
||||
|
||||
function jsTokenString(quote) {
|
||||
return function(stream, state) {
|
||||
if (!nextUntilUnescaped(stream, quote))
|
||||
state.tokenize = jsTokenBase;
|
||||
return ret("string", "string");
|
||||
};
|
||||
}
|
||||
|
||||
function jsTokenComment(stream, state) {
|
||||
var maybeEnd = false, ch;
|
||||
while (ch = stream.next()) {
|
||||
if (ch == "/" && maybeEnd) {
|
||||
state.tokenize = jsTokenBase;
|
||||
break;
|
||||
}
|
||||
maybeEnd = (ch == "*");
|
||||
}
|
||||
return ret("comment", "comment");
|
||||
}
|
||||
|
||||
// Parser
|
||||
|
||||
var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true};
|
||||
|
||||
function JSLexical(indented, column, type, align, prev, info) {
|
||||
this.indented = indented;
|
||||
this.column = column;
|
||||
this.type = type;
|
||||
this.prev = prev;
|
||||
this.info = info;
|
||||
if (align != null) this.align = align;
|
||||
}
|
||||
|
||||
function inScope(state, varname) {
|
||||
for (var v = state.localVars; v; v = v.next)
|
||||
if (v.name == varname) return true;
|
||||
}
|
||||
|
||||
function parseJS(state, style, type, content, stream) {
|
||||
var cc = state.cc;
|
||||
// Communicate our context to the combinators.
|
||||
// (Less wasteful than consing up a hundred closures on every call.)
|
||||
cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
|
||||
|
||||
if (!state.lexical.hasOwnProperty("align"))
|
||||
state.lexical.align = true;
|
||||
|
||||
while(true) {
|
||||
var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
|
||||
if (combinator(type, content)) {
|
||||
while(cc.length && cc[cc.length - 1].lex)
|
||||
cc.pop()();
|
||||
if (cx.marked) return cx.marked;
|
||||
if (type == "variable" && inScope(state, content)) return "variable-2";
|
||||
return style;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Combinator utils
|
||||
|
||||
var cx = {state: null, column: null, marked: null, cc: null};
|
||||
function pass() {
|
||||
for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
|
||||
}
|
||||
function cont() {
|
||||
pass.apply(null, arguments);
|
||||
return true;
|
||||
}
|
||||
function register(varname) {
|
||||
function inList(list) {
|
||||
for (var v = list; v; v = v.next)
|
||||
if (v.name == varname) return true;
|
||||
return false;
|
||||
}
|
||||
var state = cx.state;
|
||||
if (state.context) {
|
||||
cx.marked = "def";
|
||||
if (inList(state.localVars)) return;
|
||||
state.localVars = {name: varname, next: state.localVars};
|
||||
} else {
|
||||
if (inList(state.globalVars)) return;
|
||||
state.globalVars = {name: varname, next: state.globalVars};
|
||||
}
|
||||
}
|
||||
|
||||
// Combinators
|
||||
|
||||
var defaultVars = {name: "this", next: {name: "arguments"}};
|
||||
function pushcontext() {
|
||||
cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
|
||||
cx.state.localVars = defaultVars;
|
||||
}
|
||||
function popcontext() {
|
||||
cx.state.localVars = cx.state.context.vars;
|
||||
cx.state.context = cx.state.context.prev;
|
||||
}
|
||||
function pushlex(type, info) {
|
||||
var result = function() {
|
||||
var state = cx.state;
|
||||
state.lexical = new JSLexical(state.indented, cx.stream.column(), type, null, state.lexical, info);
|
||||
};
|
||||
result.lex = true;
|
||||
return result;
|
||||
}
|
||||
function poplex() {
|
||||
var state = cx.state;
|
||||
if (state.lexical.prev) {
|
||||
if (state.lexical.type == ")")
|
||||
state.indented = state.lexical.indented;
|
||||
state.lexical = state.lexical.prev;
|
||||
}
|
||||
}
|
||||
poplex.lex = true;
|
||||
|
||||
function expect(wanted) {
|
||||
return function(type) {
|
||||
if (type == wanted) return cont();
|
||||
else if (wanted == ";") return pass();
|
||||
else return cont(arguments.callee);
|
||||
};
|
||||
}
|
||||
|
||||
function statement(type) {
|
||||
if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
|
||||
if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
|
||||
if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
|
||||
if (type == "{") return cont(pushlex("}"), block, poplex);
|
||||
if (type == ";") return cont();
|
||||
if (type == "function") return cont(functiondef);
|
||||
if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
|
||||
poplex, statement, poplex);
|
||||
if (type == "variable") return cont(pushlex("stat"), maybelabel);
|
||||
if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
|
||||
block, poplex, poplex);
|
||||
if (type == "case") return cont(expression, expect(":"));
|
||||
if (type == "default") return cont(expect(":"));
|
||||
if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
|
||||
statement, poplex, popcontext);
|
||||
return pass(pushlex("stat"), expression, expect(";"), poplex);
|
||||
}
|
||||
function expression(type) {
|
||||
if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
|
||||
if (type == "function") return cont(functiondef);
|
||||
if (type == "keyword c") return cont(maybeexpression);
|
||||
if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeoperator);
|
||||
if (type == "operator") return cont(expression);
|
||||
if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
|
||||
if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
|
||||
return cont();
|
||||
}
|
||||
function maybeexpression(type) {
|
||||
if (type.match(/[;\}\)\],]/)) return pass();
|
||||
return pass(expression);
|
||||
}
|
||||
|
||||
function maybeoperator(type, value) {
|
||||
if (type == "operator") {
|
||||
if (/\+\+|--/.test(value)) return cont(maybeoperator);
|
||||
if (value == "?") return cont(expression, expect(":"), expression);
|
||||
return cont(expression);
|
||||
}
|
||||
if (type == ";") return;
|
||||
if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);
|
||||
if (type == ".") return cont(property, maybeoperator);
|
||||
if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
|
||||
}
|
||||
function maybelabel(type) {
|
||||
if (type == ":") return cont(poplex, statement);
|
||||
return pass(maybeoperator, expect(";"), poplex);
|
||||
}
|
||||
function property(type) {
|
||||
if (type == "variable") {cx.marked = "property"; return cont();}
|
||||
}
|
||||
function objprop(type, value) {
|
||||
if (type == "variable") {
|
||||
cx.marked = "property";
|
||||
if (value == "get" || value == "set") return cont(getterSetter);
|
||||
} else if (type == "number" || type == "string") {
|
||||
cx.marked = type + " property";
|
||||
}
|
||||
if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression);
|
||||
}
|
||||
function getterSetter(type) {
|
||||
if (type == ":") return cont(expression);
|
||||
if (type != "variable") return cont(expect(":"), expression);
|
||||
cx.marked = "property";
|
||||
return cont(functiondef);
|
||||
}
|
||||
function commasep(what, end) {
|
||||
function proceed(type) {
|
||||
if (type == ",") return cont(what, proceed);
|
||||
if (type == end) return cont();
|
||||
return cont(expect(end));
|
||||
}
|
||||
return function(type) {
|
||||
if (type == end) return cont();
|
||||
else return pass(what, proceed);
|
||||
};
|
||||
}
|
||||
function block(type) {
|
||||
if (type == "}") return cont();
|
||||
return pass(statement, block);
|
||||
}
|
||||
function maybetype(type) {
|
||||
if (type == ":") return cont(typedef);
|
||||
return pass();
|
||||
}
|
||||
function typedef(type) {
|
||||
if (type == "variable"){cx.marked = "variable-3"; return cont();}
|
||||
return pass();
|
||||
}
|
||||
function vardef1(type, value) {
|
||||
if (type == "variable") {
|
||||
register(value);
|
||||
return isTS ? cont(maybetype, vardef2) : cont(vardef2);
|
||||
}
|
||||
return pass();
|
||||
}
|
||||
function vardef2(type, value) {
|
||||
if (value == "=") return cont(expression, vardef2);
|
||||
if (type == ",") return cont(vardef1);
|
||||
}
|
||||
function forspec1(type) {
|
||||
if (type == "var") return cont(vardef1, expect(";"), forspec2);
|
||||
if (type == ";") return cont(forspec2);
|
||||
if (type == "variable") return cont(formaybein);
|
||||
return cont(forspec2);
|
||||
}
|
||||
function formaybein(_type, value) {
|
||||
if (value == "in") return cont(expression);
|
||||
return cont(maybeoperator, forspec2);
|
||||
}
|
||||
function forspec2(type, value) {
|
||||
if (type == ";") return cont(forspec3);
|
||||
if (value == "in") return cont(expression);
|
||||
return cont(expression, expect(";"), forspec3);
|
||||
}
|
||||
function forspec3(type) {
|
||||
if (type != ")") cont(expression);
|
||||
}
|
||||
function functiondef(type, value) {
|
||||
if (type == "variable") {register(value); return cont(functiondef);}
|
||||
if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext);
|
||||
}
|
||||
function funarg(type, value) {
|
||||
if (type == "variable") {register(value); return isTS ? cont(maybetype) : cont();}
|
||||
}
|
||||
|
||||
// Interface
|
||||
|
||||
return {
|
||||
startState: function(basecolumn) {
|
||||
return {
|
||||
tokenize: jsTokenBase,
|
||||
lastType: null,
|
||||
cc: [],
|
||||
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
|
||||
localVars: parserConfig.localVars,
|
||||
globalVars: parserConfig.globalVars,
|
||||
context: parserConfig.localVars && {vars: parserConfig.localVars},
|
||||
indented: 0
|
||||
};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
if (stream.sol()) {
|
||||
if (!state.lexical.hasOwnProperty("align"))
|
||||
state.lexical.align = false;
|
||||
state.indented = stream.indentation();
|
||||
}
|
||||
if (stream.eatSpace()) return null;
|
||||
var style = state.tokenize(stream, state);
|
||||
if (type == "comment") return style;
|
||||
state.lastType = type;
|
||||
return parseJS(state, style, type, content, stream);
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
if (state.tokenize == jsTokenComment) return CodeMirror.Pass;
|
||||
if (state.tokenize != jsTokenBase) return 0;
|
||||
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
|
||||
if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
|
||||
var type = lexical.type, closing = firstChar == type;
|
||||
if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? 4 : 0);
|
||||
else if (type == "form" && firstChar == "{") return lexical.indented;
|
||||
else if (type == "form") return lexical.indented + indentUnit;
|
||||
else if (type == "stat")
|
||||
return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? indentUnit : 0);
|
||||
else if (lexical.info == "switch" && !closing)
|
||||
return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
|
||||
else if (lexical.align) return lexical.column + (closing ? 0 : 1);
|
||||
else return lexical.indented + (closing ? 0 : indentUnit);
|
||||
},
|
||||
|
||||
electricChars: ":{}",
|
||||
|
||||
jsonMode: jsonMode
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/javascript", "javascript");
|
||||
CodeMirror.defineMIME("text/ecmascript", "javascript");
|
||||
CodeMirror.defineMIME("application/javascript", "javascript");
|
||||
CodeMirror.defineMIME("application/ecmascript", "javascript");
|
||||
CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
|
||||
CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
|
||||
CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
|
|
@ -0,0 +1,328 @@
|
|||
CodeMirror.defineMode("xml", function(config, parserConfig) {
|
||||
var indentUnit = config.indentUnit;
|
||||
var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1;
|
||||
|
||||
var Kludges = parserConfig.htmlMode ? {
|
||||
autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
|
||||
'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
|
||||
'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
|
||||
'track': true, 'wbr': true},
|
||||
implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
|
||||
'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
|
||||
'th': true, 'tr': true},
|
||||
contextGrabbers: {
|
||||
'dd': {'dd': true, 'dt': true},
|
||||
'dt': {'dd': true, 'dt': true},
|
||||
'li': {'li': true},
|
||||
'option': {'option': true, 'optgroup': true},
|
||||
'optgroup': {'optgroup': true},
|
||||
'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
|
||||
'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
|
||||
'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
|
||||
'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
|
||||
'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
|
||||
'rp': {'rp': true, 'rt': true},
|
||||
'rt': {'rp': true, 'rt': true},
|
||||
'tbody': {'tbody': true, 'tfoot': true},
|
||||
'td': {'td': true, 'th': true},
|
||||
'tfoot': {'tbody': true},
|
||||
'th': {'td': true, 'th': true},
|
||||
'thead': {'tbody': true, 'tfoot': true},
|
||||
'tr': {'tr': true}
|
||||
},
|
||||
doNotIndent: {"pre": true},
|
||||
allowUnquoted: true,
|
||||
allowMissing: true
|
||||
} : {
|
||||
autoSelfClosers: {},
|
||||
implicitlyClosed: {},
|
||||
contextGrabbers: {},
|
||||
doNotIndent: {},
|
||||
allowUnquoted: false,
|
||||
allowMissing: false
|
||||
};
|
||||
var alignCDATA = parserConfig.alignCDATA;
|
||||
|
||||
// Return variables for tokenizers
|
||||
var tagName, type;
|
||||
|
||||
function inText(stream, state) {
|
||||
function chain(parser) {
|
||||
state.tokenize = parser;
|
||||
return parser(stream, state);
|
||||
}
|
||||
|
||||
var ch = stream.next();
|
||||
if (ch == "<") {
|
||||
if (stream.eat("!")) {
|
||||
if (stream.eat("[")) {
|
||||
if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
|
||||
else return null;
|
||||
}
|
||||
else if (stream.match("--")) return chain(inBlock("comment", "-->"));
|
||||
else if (stream.match("DOCTYPE", true, true)) {
|
||||
stream.eatWhile(/[\w\._\-]/);
|
||||
return chain(doctype(1));
|
||||
}
|
||||
else return null;
|
||||
}
|
||||
else if (stream.eat("?")) {
|
||||
stream.eatWhile(/[\w\._\-]/);
|
||||
state.tokenize = inBlock("meta", "?>");
|
||||
return "meta";
|
||||
}
|
||||
else {
|
||||
var isClose = stream.eat("/");
|
||||
tagName = "";
|
||||
var c;
|
||||
while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
|
||||
if (!tagName) return "error";
|
||||
type = isClose ? "closeTag" : "openTag";
|
||||
state.tokenize = inTag;
|
||||
return "tag";
|
||||
}
|
||||
}
|
||||
else if (ch == "&") {
|
||||
var ok;
|
||||
if (stream.eat("#")) {
|
||||
if (stream.eat("x")) {
|
||||
ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
|
||||
} else {
|
||||
ok = stream.eatWhile(/[\d]/) && stream.eat(";");
|
||||
}
|
||||
} else {
|
||||
ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
|
||||
}
|
||||
return ok ? "atom" : "error";
|
||||
}
|
||||
else {
|
||||
stream.eatWhile(/[^&<]/);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function inTag(stream, state) {
|
||||
var ch = stream.next();
|
||||
if (ch == ">" || (ch == "/" && stream.eat(">"))) {
|
||||
state.tokenize = inText;
|
||||
type = ch == ">" ? "endTag" : "selfcloseTag";
|
||||
return "tag";
|
||||
}
|
||||
else if (ch == "=") {
|
||||
type = "equals";
|
||||
return null;
|
||||
}
|
||||
else if (/[\'\"]/.test(ch)) {
|
||||
state.tokenize = inAttribute(ch);
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
else {
|
||||
stream.eatWhile(/[^\s\u00a0=<>\"\']/);
|
||||
return "word";
|
||||
}
|
||||
}
|
||||
|
||||
function inAttribute(quote) {
|
||||
return function(stream, state) {
|
||||
while (!stream.eol()) {
|
||||
if (stream.next() == quote) {
|
||||
state.tokenize = inTag;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return "string";
|
||||
};
|
||||
}
|
||||
|
||||
function inBlock(style, terminator) {
|
||||
return function(stream, state) {
|
||||
while (!stream.eol()) {
|
||||
if (stream.match(terminator)) {
|
||||
state.tokenize = inText;
|
||||
break;
|
||||
}
|
||||
stream.next();
|
||||
}
|
||||
return style;
|
||||
};
|
||||
}
|
||||
function doctype(depth) {
|
||||
return function(stream, state) {
|
||||
var ch;
|
||||
while ((ch = stream.next()) != null) {
|
||||
if (ch == "<") {
|
||||
state.tokenize = doctype(depth + 1);
|
||||
return state.tokenize(stream, state);
|
||||
} else if (ch == ">") {
|
||||
if (depth == 1) {
|
||||
state.tokenize = inText;
|
||||
break;
|
||||
} else {
|
||||
state.tokenize = doctype(depth - 1);
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
return "meta";
|
||||
};
|
||||
}
|
||||
|
||||
var curState, curStream, setStyle;
|
||||
function pass() {
|
||||
for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
|
||||
}
|
||||
function cont() {
|
||||
pass.apply(null, arguments);
|
||||
return true;
|
||||
}
|
||||
|
||||
function pushContext(tagName, startOfLine) {
|
||||
var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent);
|
||||
curState.context = {
|
||||
prev: curState.context,
|
||||
tagName: tagName,
|
||||
indent: curState.indented,
|
||||
startOfLine: startOfLine,
|
||||
noIndent: noIndent
|
||||
};
|
||||
}
|
||||
function popContext() {
|
||||
if (curState.context) curState.context = curState.context.prev;
|
||||
}
|
||||
|
||||
function element(type) {
|
||||
if (type == "openTag") {
|
||||
curState.tagName = tagName;
|
||||
curState.tagStart = curStream.column();
|
||||
return cont(attributes, endtag(curState.startOfLine));
|
||||
} else if (type == "closeTag") {
|
||||
var err = false;
|
||||
if (curState.context) {
|
||||
if (curState.context.tagName != tagName) {
|
||||
if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())) {
|
||||
popContext();
|
||||
}
|
||||
err = !curState.context || curState.context.tagName != tagName;
|
||||
}
|
||||
} else {
|
||||
err = true;
|
||||
}
|
||||
if (err) setStyle = "error";
|
||||
return cont(endclosetag(err));
|
||||
}
|
||||
return cont();
|
||||
}
|
||||
function endtag(startOfLine) {
|
||||
return function(type) {
|
||||
var tagName = curState.tagName;
|
||||
curState.tagName = curState.tagStart = null;
|
||||
if (type == "selfcloseTag" ||
|
||||
(type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(tagName.toLowerCase()))) {
|
||||
maybePopContext(tagName.toLowerCase());
|
||||
return cont();
|
||||
}
|
||||
if (type == "endTag") {
|
||||
maybePopContext(tagName.toLowerCase());
|
||||
pushContext(tagName, startOfLine);
|
||||
return cont();
|
||||
}
|
||||
return cont();
|
||||
};
|
||||
}
|
||||
function endclosetag(err) {
|
||||
return function(type) {
|
||||
if (err) setStyle = "error";
|
||||
if (type == "endTag") { popContext(); return cont(); }
|
||||
setStyle = "error";
|
||||
return cont(arguments.callee);
|
||||
};
|
||||
}
|
||||
function maybePopContext(nextTagName) {
|
||||
var parentTagName;
|
||||
while (true) {
|
||||
if (!curState.context) {
|
||||
return;
|
||||
}
|
||||
parentTagName = curState.context.tagName.toLowerCase();
|
||||
if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
|
||||
!Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
|
||||
return;
|
||||
}
|
||||
popContext();
|
||||
}
|
||||
}
|
||||
|
||||
function attributes(type) {
|
||||
if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);}
|
||||
if (type == "endTag" || type == "selfcloseTag") return pass();
|
||||
setStyle = "error";
|
||||
return cont(attributes);
|
||||
}
|
||||
function attribute(type) {
|
||||
if (type == "equals") return cont(attvalue, attributes);
|
||||
if (!Kludges.allowMissing) setStyle = "error";
|
||||
else if (type == "word") setStyle = "attribute";
|
||||
return (type == "endTag" || type == "selfcloseTag") ? pass() : cont();
|
||||
}
|
||||
function attvalue(type) {
|
||||
if (type == "string") return cont(attvaluemaybe);
|
||||
if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();}
|
||||
setStyle = "error";
|
||||
return (type == "endTag" || type == "selfCloseTag") ? pass() : cont();
|
||||
}
|
||||
function attvaluemaybe(type) {
|
||||
if (type == "string") return cont(attvaluemaybe);
|
||||
else return pass();
|
||||
}
|
||||
|
||||
return {
|
||||
startState: function() {
|
||||
return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, tagStart: null, context: null};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
if (!state.tagName && stream.sol()) {
|
||||
state.startOfLine = true;
|
||||
state.indented = stream.indentation();
|
||||
}
|
||||
if (stream.eatSpace()) return null;
|
||||
|
||||
setStyle = type = tagName = null;
|
||||
var style = state.tokenize(stream, state);
|
||||
state.type = type;
|
||||
if ((style || type) && style != "comment") {
|
||||
curState = state; curStream = stream;
|
||||
while (true) {
|
||||
var comb = state.cc.pop() || element;
|
||||
if (comb(type || style)) break;
|
||||
}
|
||||
}
|
||||
state.startOfLine = false;
|
||||
return setStyle || style;
|
||||
},
|
||||
|
||||
indent: function(state, textAfter, fullLine) {
|
||||
var context = state.context;
|
||||
if ((state.tokenize != inTag && state.tokenize != inText) ||
|
||||
context && context.noIndent)
|
||||
return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
|
||||
if (state.tagName) return state.tagStart + indentUnit * multilineTagIndentFactor;
|
||||
if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
|
||||
if (context && /^<\//.test(textAfter))
|
||||
context = context.prev;
|
||||
while (context && !context.startOfLine)
|
||||
context = context.prev;
|
||||
if (context) return context.indent + indentUnit;
|
||||
else return 0;
|
||||
},
|
||||
|
||||
electricChars: "/",
|
||||
|
||||
configuration: parserConfig.htmlMode ? "html" : "xml"
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/xml", "xml");
|
||||
CodeMirror.defineMIME("application/xml", "xml");
|
||||
if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
|
||||
CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'af', {
|
||||
toolbar: 'Bron',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'ar', {
|
||||
toolbar: 'المصدر',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'bg', {
|
||||
toolbar: 'Източник',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'bn', {
|
||||
toolbar: 'সোর্স',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'bs', {
|
||||
toolbar: 'HTML kôd',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'ca', {
|
||||
toolbar: 'Codi font',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'cs', {
|
||||
toolbar: 'Zdroj',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'cy', {
|
||||
toolbar: 'HTML',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'da', {
|
||||
toolbar: 'Kilde',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'de', {
|
||||
toolbar: 'Quellcode',
|
||||
searchCode: 'Quellcode durchsuchen',
|
||||
autoFormat: 'Auswahl formatieren',
|
||||
commentSelectedRange: 'Auswahl auskommentieren',
|
||||
uncommentSelectedRange: 'Auskommentierung entferen',
|
||||
autoCompleteToggle: 'HTML Tag Autvervollständigen de-/aktivieren'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'el', {
|
||||
toolbar: 'HTML κώδικας',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'en-au', {
|
||||
toolbar: 'Source',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'en-ca', {
|
||||
toolbar: 'Source',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'en-gb', {
|
||||
toolbar: 'Source',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'en', {
|
||||
toolbar: 'Source',
|
||||
searchCode: 'Search Source',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection',
|
||||
autoCompleteToggle: 'Enable/Disable HTML Tag Autocomplete'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'eo', {
|
||||
toolbar: 'Fonto',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'es', {
|
||||
toolbar: 'Fuente HTML',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'et', {
|
||||
toolbar: 'Lähtekood',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'eu', {
|
||||
toolbar: 'HTML Iturburua',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'fa', {
|
||||
toolbar: 'منبع',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'fi', {
|
||||
toolbar: 'Koodi',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'fo', {
|
||||
toolbar: 'Kelda',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'fr-ca', {
|
||||
toolbar: 'Source',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'fr', {
|
||||
toolbar: 'Source',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'gl', {
|
||||
toolbar: 'Código Fonte',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'gu', {
|
||||
toolbar: 'મૂળ કે પ્રાથમિક દસ્તાવેજ',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'he', {
|
||||
toolbar: 'מקור',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'hi', {
|
||||
toolbar: 'सोर्स',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'hr', {
|
||||
toolbar: 'Kôd',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'hu', {
|
||||
toolbar: 'Forráskód',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'is', {
|
||||
toolbar: 'Kóði',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'it', {
|
||||
toolbar: 'Codice Sorgente',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'ja', {
|
||||
toolbar: 'ソース',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'ka', {
|
||||
toolbar: 'კოდები',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'km', {
|
||||
toolbar: 'កូត',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'ko', {
|
||||
toolbar: '소스',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'ku', {
|
||||
toolbar: 'سەرچاوە',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'lt', {
|
||||
toolbar: 'Šaltinis',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'lv', {
|
||||
toolbar: 'HTML kods',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'mk', {
|
||||
toolbar: 'Source',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'mn', {
|
||||
toolbar: 'Код',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'ms', {
|
||||
toolbar: 'Sumber',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'nb', {
|
||||
toolbar: 'Kilde',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'nl', {
|
||||
toolbar: 'Code',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'no', {
|
||||
toolbar: 'Kilde',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'pl', {
|
||||
toolbar: 'Źródło dokumentu',
|
||||
autoFormat: 'Sformatuj zaznaczenie',
|
||||
commentSelectedRange: 'Zakomentuj zaznaczenie',
|
||||
uncommentSelectedRange: 'Odkomentuj zaznaczenie'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'pt-br', {
|
||||
toolbar: 'Código-Fonte',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'pt', {
|
||||
toolbar: 'Fonte',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'ro', {
|
||||
toolbar: 'Sursa',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'ru', {
|
||||
toolbar: 'Источник',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'sk', {
|
||||
toolbar: 'Zdroj',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'sl', {
|
||||
toolbar: 'Izvorna koda',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
CKEDITOR.plugins.setLang( 'codemirror', 'sr-latn', {
|
||||
toolbar: 'Kôd',
|
||||
autoFormat: 'Format Selection',
|
||||
commentSelectedRange: 'Comment Selection',
|
||||
uncommentSelectedRange: 'Uncomment Selection'
|
||||
});
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue