liquid_cms 0.3.0.8 → 0.3.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/CHANGELOG.rdoc +7 -0
- data/TODO.rdoc +1 -1
- data/app/controllers/cms/main_controller.rb +3 -2
- data/app/helpers/cms/common_helper.rb +9 -2
- data/app/helpers/cms/components_helper.rb +10 -4
- data/app/liquid/filters/cms_filters.rb +1 -0
- data/app/models/cms/component.rb +4 -0
- data/app/views/cms/assets/_list.html.erb +4 -4
- data/app/views/cms/components/_list.html.erb +5 -1
- data/app/views/cms/components/edit.html.erb +1 -1
- data/app/views/cms/pages/_list.html.erb +4 -4
- data/app/views/cms/shared/_sidebar.html.erb +31 -8
- data/app/views/layouts/cms.html.erb +5 -2
- data/config/initializers/cms/simple_form_updates.rb +2 -2
- data/config/locales/cms/en.yml +3 -2
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/LICENSE +0 -0
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/css/csscolors.css +0 -0
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/css/docs.css +17 -3
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/css/font.js +15 -0
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/css/jscolors.css +0 -0
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/css/sparqlcolors.css +0 -0
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/css/xmlcolors.css +0 -0
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/codemirror.js +59 -26
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/editor.js +149 -71
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/highlight.js +2 -2
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/mirrorframe.js +2 -2
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/parsecss.js +5 -3
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/parsedummy.js +0 -0
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/parsehtmlmixed.js +28 -9
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/parsejavascript.js +0 -0
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/parsesparql.js +0 -0
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/parsexml.js +6 -1
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/select.js +48 -21
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/stringstream.js +15 -1
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/tokenize.js +0 -0
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/tokenizejavascript.js +1 -1
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/undo.js +17 -14
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/unittests.js +44 -0
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/js/util.js +6 -3
- data/lib/generators/liquid_cms/templates/public/cms/javascripts/cms.js +15 -1
- data/lib/generators/liquid_cms/templates/public/cms/javascripts/livepipe.js +181 -0
- data/lib/generators/liquid_cms/templates/public/cms/javascripts/tabs.js +149 -0
- data/lib/generators/liquid_cms/templates/public/cms/stylesheets/ie9.css +4 -0
- data/lib/generators/liquid_cms/templates/public/cms/stylesheets/sidebar.css +132 -0
- data/lib/generators/liquid_cms/templates/public/cms/stylesheets/styles.css +1 -74
- data/lib/generators/liquid_cms/templates/public/cms/stylesheets/themes/dark.css +2 -1
- data/lib/liquid_cms/context.rb +4 -0
- data/lib/liquid_cms/version.rb +1 -1
- data/liquid_cms.gemspec +1 -1
- data/test/rails_app/Gemfile +1 -2
- data/test/rails_app/Gemfile.lock +56 -62
- metadata +24 -16
- data/Gemfile.lock +0 -122
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/bigtest.html +0 -1296
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/css/people.jpg +0 -0
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/csstest.html +0 -60
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/highlight.html +0 -82
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/htmltest.html +0 -52
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/index.html +0 -245
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/jstest.html +0 -56
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/manual.html +0 -759
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/mixedtest.html +0 -52
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/sparqltest.html +0 -41
- data/lib/generators/liquid_cms/templates/public/cms/codemirror/story.html +0 -671
data/.gitignore
CHANGED
data/CHANGELOG.rdoc
CHANGED
data/TODO.rdoc
CHANGED
@@ -3,6 +3,6 @@
|
|
3
3
|
* No functions are currently limited to specific user roles. All CMS users can perform the same actions.
|
4
4
|
* Implement caching and expiration logic.
|
5
5
|
* Provide example apache/nginx/etc. conf files that properly scope cms assets for each context.
|
6
|
-
* Generate CMS documentation from rdoc comments in source files
|
6
|
+
* Generate CMS documentation from rdoc comments in source files?
|
7
7
|
* Search functions. Find templates based on search text.
|
8
8
|
* Missing tests... add more coverage.
|
@@ -5,7 +5,7 @@ class Cms::MainController < Cms::SetupController
|
|
5
5
|
|
6
6
|
unloadable
|
7
7
|
|
8
|
-
before_filter :
|
8
|
+
before_filter :load_resources
|
9
9
|
|
10
10
|
authenticate_user :all, :only => %w(index)
|
11
11
|
|
@@ -14,10 +14,11 @@ class Cms::MainController < Cms::SetupController
|
|
14
14
|
end
|
15
15
|
|
16
16
|
protected
|
17
|
-
def
|
17
|
+
def load_resources
|
18
18
|
@context = Cms::Context.new(@cms_context)
|
19
19
|
|
20
20
|
@pages = @context.pages.ordered.all(:conditions => {:layout_page_id => nil})
|
21
21
|
@assets = @context.assets.ordered
|
22
|
+
@components = @context.components
|
22
23
|
end
|
23
24
|
end
|
@@ -1,4 +1,12 @@
|
|
1
1
|
module Cms::CommonHelper
|
2
|
+
# js cookie accessor
|
3
|
+
def cookie_jar(key)
|
4
|
+
# if the cookie hasn't been set, need to return '{}' to return a proper hash
|
5
|
+
# and if the cookie has been set, but is 'null', we need to then return a ruby hash
|
6
|
+
# __CJ_ is the cookiejar js lib postfix value for cookies
|
7
|
+
ActiveSupport::JSON.decode(cookies["__CJ_#{key}".to_sym] || '{}') || {}
|
8
|
+
end
|
9
|
+
|
2
10
|
def cms_icon(name, options = {})
|
3
11
|
image_tag "/cms/images/icons/#{name}", options.merge(:size => '16x16')
|
4
12
|
end
|
@@ -95,7 +103,6 @@ module Cms::CommonHelper
|
|
95
103
|
end
|
96
104
|
|
97
105
|
def asset_preview_option
|
98
|
-
|
99
|
-
ActiveSupport::JSON.decode(cookies[:__CJ_toggle] || '{}')['on'] == false ? 'style="display:none"' : ''
|
106
|
+
cookie_jar('toggle')['on'] == false ? 'style="display:none"' : ''
|
100
107
|
end
|
101
108
|
end
|
@@ -1,4 +1,8 @@
|
|
1
1
|
module Cms::ComponentsHelper
|
2
|
+
def component_folder_open?(folder_id)
|
3
|
+
cookie_jar('component_folders')[folder_id].present?
|
4
|
+
end
|
5
|
+
|
2
6
|
def component_edit_link(path)
|
3
7
|
full_path = Cms::Component.component_path(@context, path)
|
4
8
|
link_to(truncate(File.basename(path), :length => 15), {:controller => 'cms/components', :action => 'edit', :url => CGI::escape(full_path)})
|
@@ -9,15 +13,17 @@ module Cms::ComponentsHelper
|
|
9
13
|
link_to(cms_icon('delete.png', :title => 'Delete'), {:controller => 'cms/components', :action => 'destroy', :url => CGI::escape(full_path)}, :confirm => "Are you sure you want to remove '#{full_path}'?")
|
10
14
|
end
|
11
15
|
|
12
|
-
def list_files(
|
16
|
+
def list_files(files, hidden = false)
|
13
17
|
html = ''
|
14
18
|
html += hidden ? %[<ul class="tree" style="display:none">] : %[<ul class="tree">]
|
15
|
-
for file in
|
19
|
+
for file in files do
|
16
20
|
html += "<li>"
|
17
21
|
if File.directory?(file)
|
18
|
-
|
22
|
+
folder_id = "folder_#{Digest::MD5.hexdigest(file)}"
|
23
|
+
|
24
|
+
html += cms_icon('folder.png', :class => 'folder', :id => folder_id) + ' ' + component_delete_link(file) + ' '
|
19
25
|
html += content_tag(:span, File.basename(file), :title => Cms::Component.component_path(@context, file))
|
20
|
-
html += list_files(file,
|
26
|
+
html += list_files(Cms::Component.files(file), !component_folder_open?(folder_id))
|
21
27
|
else
|
22
28
|
html += file_type_icon(File.basename(file)) + ' '
|
23
29
|
html += component_delete_link(file) + ' '
|
data/app/models/cms/component.rb
CHANGED
@@ -21,6 +21,10 @@ class Cms::Component
|
|
21
21
|
path.sub(full_path(context).to_s + "/", '')
|
22
22
|
end
|
23
23
|
|
24
|
+
def self.files(path)
|
25
|
+
Dir[File.expand_path(path) + "/*"]
|
26
|
+
end
|
27
|
+
|
24
28
|
def self.valid_type?(file)
|
25
29
|
%w(.css .js .png .jpg .jpeg .gif .json .xml .fla .ico).include?(File.extname(file).downcase)
|
26
30
|
end
|
@@ -1,4 +1,8 @@
|
|
1
1
|
<div id="assets">
|
2
|
+
<p>
|
3
|
+
<%= cms_icon 'picture_add.png' %> <%= link_to t('assets.actions.index.new_link'), new_cms_asset_path %>
|
4
|
+
</p>
|
5
|
+
|
2
6
|
<% if @assets.empty? %>
|
3
7
|
<p><%= t 'assets.actions.index.none' %></p>
|
4
8
|
<% else %>
|
@@ -7,8 +11,4 @@
|
|
7
11
|
<%= render :partial => 'cms/assets/asset', :collection => @assets %>
|
8
12
|
</ul>
|
9
13
|
<% end %>
|
10
|
-
|
11
|
-
<p>
|
12
|
-
<%= cms_icon 'picture_add.png' %> <%= link_to t('assets.actions.index.new_link'), new_cms_asset_path %>
|
13
|
-
</p>
|
14
14
|
</div>
|
@@ -4,5 +4,9 @@
|
|
4
4
|
<%= submit_tag 'Upload' %> <em>.zip files only</em>
|
5
5
|
<% end %>
|
6
6
|
|
7
|
-
|
7
|
+
<% if @components.empty? %>
|
8
|
+
<p><%= t 'components.actions.index.none' %></p>
|
9
|
+
<% else %>
|
10
|
+
<%= list_files @components %>
|
11
|
+
<% end %>
|
8
12
|
</div>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<h2>Edit Component File</h2>
|
2
2
|
|
3
|
-
|
3
|
+
<%= form_tag({:controller => 'cms/components', :action => 'update', :url => CGI::escape(@component.path)}, :class => 'simple_form') do %>
|
4
4
|
<div class="string required">
|
5
5
|
<%= label_tag :name, nil, :class => 'string required' %> <%= text_field_tag :name, @component.path, :readonly => true, :class => 'string required' %>
|
6
6
|
</div>
|
@@ -1,4 +1,8 @@
|
|
1
1
|
<div id="pages">
|
2
|
+
<p>
|
3
|
+
<%= cms_icon 'page_add.png' %> <%= link_to t('pages.actions.index.new_link'), new_cms_page_path %>
|
4
|
+
</p>
|
5
|
+
|
2
6
|
<% if @pages.empty? %>
|
3
7
|
<p><%= t 'pages.actions.index.none' %></p>
|
4
8
|
<% else %>
|
@@ -6,8 +10,4 @@
|
|
6
10
|
<%= render :partial => 'cms/pages/page', :collection => @pages %>
|
7
11
|
</ul>
|
8
12
|
<% end %>
|
9
|
-
|
10
|
-
<p>
|
11
|
-
<%= cms_icon 'page_add.png' %> <%= link_to t('pages.actions.index.new_link'), new_cms_page_path %>
|
12
|
-
</p>
|
13
13
|
</div>
|
@@ -1,11 +1,34 @@
|
|
1
|
-
<
|
2
|
-
|
1
|
+
<ul id="cms_menus" class="tabs clearfix">
|
2
|
+
<li><%= link_to t('pages.actions.index.title'), '#cms_pages' %></li>
|
3
|
+
<li><%= link_to t('assets.actions.index.title'), '#cms_assets' %></li>
|
4
|
+
<li><%= link_to t('components.actions.index.title'), '#cms_components' %></li>
|
5
|
+
</ul>
|
3
6
|
|
4
|
-
<
|
5
|
-
|
7
|
+
<div id="tab_container">
|
8
|
+
<div id="cms_pages">
|
9
|
+
<h2><%= t 'pages.actions.index.title' %></h2>
|
10
|
+
<%= render 'cms/pages/list' %>
|
11
|
+
</div>
|
6
12
|
|
7
|
-
<
|
8
|
-
|
13
|
+
<div id="cms_assets">
|
14
|
+
<h2><%= t 'assets.actions.index.title' %></h2>
|
15
|
+
<%= render 'cms/assets/list' %>
|
16
|
+
</div>
|
9
17
|
|
10
|
-
<
|
11
|
-
<
|
18
|
+
<div id="cms_components">
|
19
|
+
<h2><%= t 'components.actions.index.title' %></h2>
|
20
|
+
<%= render 'cms/components/list' %>
|
21
|
+
</div>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
<%= javascript_tag do %>
|
25
|
+
new Control.Tabs('cms_menus', {
|
26
|
+
defaultTab: jar.get('active_tab') || 'first',
|
27
|
+
afterChange: function(new_container) {
|
28
|
+
// save the active tab
|
29
|
+
jar.put('active_tab', new_container.getAttribute('id'));
|
30
|
+
}
|
31
|
+
});
|
32
|
+
<% end %>
|
33
|
+
|
34
|
+
<p class="documentation"><%= cms_icon 'page.png' %> <%= link_to 'Documentation', cms_documentation_index_path %></p>
|
@@ -5,15 +5,18 @@
|
|
5
5
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
|
6
6
|
<title>Liquid CMS</title>
|
7
7
|
<%= javascript_include_tag 'prototype', 'effects', 'rails' %>
|
8
|
-
<%= javascript_include_tag '/cms/javascripts/humanmsg', '/cms/javascripts/cookiejar', '/cms/javascripts/remote_helpers', '/cms/javascripts/cms' %>
|
8
|
+
<%= javascript_include_tag '/cms/javascripts/humanmsg', '/cms/javascripts/cookiejar', '/cms/javascripts/remote_helpers', '/cms/javascripts/cms', '/cms/javascripts/livepipe', '/cms/javascripts/tabs', :cache => 'cms_scripts' %>
|
9
9
|
<%= javascript_include_tag '/cms/codemirror/js/codemirror' %>
|
10
10
|
<%= stylesheet_link_tag '/cms/stylesheets/simple_form' %>
|
11
|
-
<%= stylesheet_link_tag '/cms/stylesheets/clearfix', '/cms/stylesheets/humanmsg', '/cms/stylesheets/styles' %>
|
11
|
+
<%= stylesheet_link_tag '/cms/stylesheets/clearfix', '/cms/stylesheets/humanmsg', '/cms/stylesheets/styles', '/cms/stylesheets/sidebar', :cache => 'cms_styles' %>
|
12
12
|
<%= stylesheet_link_tag '/cms/stylesheets/themes/dark' %>
|
13
13
|
<%= yield :cms_styles %>
|
14
14
|
<!--[if lte IE 8]>
|
15
15
|
<%= stylesheet_link_tag '/cms/stylesheets/ie' %>
|
16
16
|
<![endif]-->
|
17
|
+
<!--[if lte IE 9]>
|
18
|
+
<%= stylesheet_link_tag '/cms/stylesheets/ie9' %>
|
19
|
+
<![endif]-->
|
17
20
|
<%= csrf_meta_tag %>
|
18
21
|
</head>
|
19
22
|
<body id="cms" class="cms_<%= params[:controller].camelize.demodulize.downcase %>">
|
@@ -1,10 +1,10 @@
|
|
1
1
|
class SimpleForm::FormBuilder
|
2
2
|
def commit_button_or_cancel
|
3
|
-
|
3
|
+
template.content_tag :div, :class => 'buttons' do
|
4
4
|
String.new.tap do |html|
|
5
5
|
html << button(:submit)
|
6
6
|
html << " or "
|
7
|
-
html << template.link_to(
|
7
|
+
html << template.link_to(template.t('simple_form.buttons.cancel'), :back, :class => 'cancel')
|
8
8
|
end.html_safe
|
9
9
|
end
|
10
10
|
end
|
data/config/locales/cms/en.yml
CHANGED
@@ -2,7 +2,7 @@ en:
|
|
2
2
|
pages:
|
3
3
|
actions:
|
4
4
|
index:
|
5
|
-
title: '
|
5
|
+
title: 'Pages'
|
6
6
|
none: 'There are currently no pages.'
|
7
7
|
new_link: 'Create a new page'
|
8
8
|
new:
|
@@ -17,7 +17,7 @@ en:
|
|
17
17
|
assets:
|
18
18
|
actions:
|
19
19
|
index:
|
20
|
-
title: '
|
20
|
+
title: 'Assets'
|
21
21
|
none: 'There are currently no assets.'
|
22
22
|
new_link: 'Upload a new asset'
|
23
23
|
new:
|
@@ -33,6 +33,7 @@ en:
|
|
33
33
|
actions:
|
34
34
|
index:
|
35
35
|
title: 'Components'
|
36
|
+
none: 'There are currently no components.'
|
36
37
|
|
37
38
|
simple_form:
|
38
39
|
"yes": 'Yes'
|
File without changes
|
File without changes
|
@@ -1,10 +1,13 @@
|
|
1
1
|
body {
|
2
|
-
font-family:
|
2
|
+
font-family: Arial, sans-serif;
|
3
3
|
line-height: 1.5;
|
4
4
|
max-width: 64.3em;
|
5
5
|
margin: 3em auto;
|
6
6
|
padding: 0 1em;
|
7
7
|
}
|
8
|
+
body.droid {
|
9
|
+
font-family: Droid Sans, Arial, sans-serif;
|
10
|
+
}
|
8
11
|
|
9
12
|
h1 {
|
10
13
|
letter-spacing: -3px;
|
@@ -27,7 +30,7 @@ h3 {
|
|
27
30
|
}
|
28
31
|
|
29
32
|
pre {
|
30
|
-
font-family:
|
33
|
+
font-family: Courier New, monospaced;
|
31
34
|
background-color: #eee;
|
32
35
|
-moz-border-radius: 6px;
|
33
36
|
-webkit-border-radius: 6px;
|
@@ -44,6 +47,13 @@ pre.code {
|
|
44
47
|
padding: .5em 1em;
|
45
48
|
line-height: 1.2em;
|
46
49
|
margin-top: .5em;
|
50
|
+
position: relative;
|
51
|
+
}
|
52
|
+
|
53
|
+
img.logo {
|
54
|
+
position: absolute;
|
55
|
+
right: -25px;
|
56
|
+
bottom: 4px;
|
47
57
|
}
|
48
58
|
|
49
59
|
a:link, a:visited, .quasilink {
|
@@ -52,10 +62,14 @@ a:link, a:visited, .quasilink {
|
|
52
62
|
text-decoration: none;
|
53
63
|
}
|
54
64
|
|
55
|
-
a:hover {
|
65
|
+
a:hover, .quasilink:hover {
|
56
66
|
color: #800004;
|
57
67
|
}
|
58
68
|
|
69
|
+
h1 a:link, h1 a:visited, h1 a:hover {
|
70
|
+
color: black;
|
71
|
+
}
|
72
|
+
|
59
73
|
ul {
|
60
74
|
margin: 0;
|
61
75
|
padding-left: 1.2em;
|
@@ -0,0 +1,15 @@
|
|
1
|
+
function waitForStyles() {
|
2
|
+
for (var i = 0; i < document.styleSheets.length; i++)
|
3
|
+
if (/googleapis/.test(document.styleSheets[i].href))
|
4
|
+
return document.body.className += " droid";
|
5
|
+
setTimeout(waitForStyles, 100);
|
6
|
+
}
|
7
|
+
setTimeout(function() {
|
8
|
+
if (/AppleWebKit/.test(navigator.userAgent) && /iP[oa]d|iPhone/.test(navigator.userAgent)) return;
|
9
|
+
var link = document.createElement("LINK");
|
10
|
+
link.type = "text/css";
|
11
|
+
link.rel = "stylesheet";
|
12
|
+
link.href = "http://fonts.googleapis.com/css?family=Droid+Sans|Droid+Sans:bold";
|
13
|
+
document.documentElement.getElementsByTagName("HEAD")[0].appendChild(link);
|
14
|
+
waitForStyles();
|
15
|
+
}, 20);
|
File without changes
|
File without changes
|
File without changes
|
@@ -21,6 +21,12 @@ var CodeMirror = (function(){
|
|
21
21
|
for (var i = 0; i < array.length; i++)
|
22
22
|
action(array[i]);
|
23
23
|
}
|
24
|
+
function createHTMLElement(el) {
|
25
|
+
if (document.createElementNS && document.documentElement.namespaceURI !== null)
|
26
|
+
return document.createElementNS("http://www.w3.org/1999/xhtml", el)
|
27
|
+
else
|
28
|
+
return document.createElement(el)
|
29
|
+
}
|
24
30
|
|
25
31
|
// These default options can be overridden by passing a set of
|
26
32
|
// options to a specific CodeMirror constructor. See manual.html for
|
@@ -37,6 +43,7 @@ var CodeMirror = (function(){
|
|
37
43
|
lineNumberTime: 50,
|
38
44
|
continuousScanning: false,
|
39
45
|
saveFunction: null,
|
46
|
+
onLoad: null,
|
40
47
|
onChange: null,
|
41
48
|
undoDepth: 50,
|
42
49
|
undoDelay: 800,
|
@@ -47,22 +54,27 @@ var CodeMirror = (function(){
|
|
47
54
|
height: "300px",
|
48
55
|
minHeight: 100,
|
49
56
|
autoMatchParens: false,
|
57
|
+
markParen: null,
|
58
|
+
unmarkParen: null,
|
50
59
|
parserConfig: null,
|
51
60
|
tabMode: "indent", // or "spaces", "default", "shift"
|
52
61
|
enterMode: "indent", // or "keep", "flat"
|
53
62
|
electricChars: true,
|
54
63
|
reindentOnLoad: false,
|
55
64
|
activeTokens: null,
|
56
|
-
|
65
|
+
onCursorActivity: null,
|
57
66
|
lineNumbers: false,
|
58
67
|
firstLineNumber: 1,
|
68
|
+
onLineNumberClick: null,
|
59
69
|
indentUnit: 2,
|
60
|
-
domain: null
|
70
|
+
domain: null,
|
71
|
+
noScriptCaching: false,
|
72
|
+
incrementalLoading: false
|
61
73
|
});
|
62
74
|
|
63
75
|
function addLineNumberDiv(container, firstNum) {
|
64
|
-
var nums =
|
65
|
-
scroller =
|
76
|
+
var nums = createHTMLElement("div"),
|
77
|
+
scroller = createHTMLElement("div");
|
66
78
|
nums.style.position = "absolute";
|
67
79
|
nums.style.height = "100%";
|
68
80
|
if (nums.style.setExpression) {
|
@@ -87,18 +99,19 @@ var CodeMirror = (function(){
|
|
87
99
|
if (typeof options.stylesheet == "string")
|
88
100
|
options.stylesheet = [options.stylesheet];
|
89
101
|
|
90
|
-
var
|
102
|
+
var sp = " spellcheck=\"" + (options.disableSpellcheck ? "false" : "true") + "\"";
|
103
|
+
var html = ["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\"><html" + sp + "><head>"];
|
91
104
|
// Hack to work around a bunch of IE8-specific problems.
|
92
105
|
html.push("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=EmulateIE7\"/>");
|
106
|
+
var queryStr = options.noScriptCaching ? "?nocache=" + new Date().getTime().toString(16) : "";
|
93
107
|
forEach(options.stylesheet, function(file) {
|
94
|
-
html.push("<link rel=\"stylesheet\" type=\"text/css\" href=\"" + file + "\"/>");
|
108
|
+
html.push("<link rel=\"stylesheet\" type=\"text/css\" href=\"" + file + queryStr + "\"/>");
|
95
109
|
});
|
96
110
|
forEach(options.basefiles.concat(options.parserfile), function(file) {
|
97
111
|
if (!/^https?:/.test(file)) file = options.path + file;
|
98
|
-
html.push("<script type=\"text/javascript\" src=\"" + file + "\"><" + "/script>");
|
112
|
+
html.push("<script type=\"text/javascript\" src=\"" + file + queryStr + "\"><" + "/script>");
|
99
113
|
});
|
100
|
-
html.push("</head><body style=\"border-width: 0;\" class=\"editbox\"
|
101
|
-
(options.disableSpellcheck ? "false" : "true") + "\"></body></html>");
|
114
|
+
html.push("</head><body style=\"border-width: 0;\" class=\"editbox\"" + sp + "></body></html>");
|
102
115
|
return html.join("");
|
103
116
|
}
|
104
117
|
|
@@ -112,8 +125,9 @@ var CodeMirror = (function(){
|
|
112
125
|
// Backward compatibility for deprecated options.
|
113
126
|
if (options.dumbTabs) options.tabMode = "spaces";
|
114
127
|
else if (options.normalTab) options.tabMode = "default";
|
128
|
+
if (options.cursorActivity) options.onCursorActivity = options.cursorActivity;
|
115
129
|
|
116
|
-
var frame = this.frame =
|
130
|
+
var frame = this.frame = createHTMLElement("iframe");
|
117
131
|
if (options.iframeClass) frame.className = options.iframeClass;
|
118
132
|
frame.frameBorder = 0;
|
119
133
|
frame.style.border = "0";
|
@@ -123,17 +137,18 @@ var CodeMirror = (function(){
|
|
123
137
|
// always add it, redundant as it sounds.
|
124
138
|
frame.style.display = "block";
|
125
139
|
|
126
|
-
var div = this.wrapping =
|
140
|
+
var div = this.wrapping = createHTMLElement("div");
|
127
141
|
div.style.position = "relative";
|
128
142
|
div.className = "CodeMirror-wrapping";
|
129
143
|
div.style.width = options.width;
|
130
144
|
div.style.height = (options.height == "dynamic") ? options.minHeight + "px" : options.height;
|
131
145
|
// This is used by Editor.reroutePasteEvent
|
132
|
-
var teHack = this.textareaHack =
|
146
|
+
var teHack = this.textareaHack = createHTMLElement("textarea");
|
133
147
|
div.appendChild(teHack);
|
134
148
|
teHack.style.position = "absolute";
|
135
149
|
teHack.style.left = "-10000px";
|
136
150
|
teHack.style.width = "10px";
|
151
|
+
teHack.tabIndex = 100000;
|
137
152
|
|
138
153
|
// Link back to this object, so that the editor can fetch options
|
139
154
|
// and add a reference to itself.
|
@@ -163,7 +178,9 @@ var CodeMirror = (function(){
|
|
163
178
|
|
164
179
|
CodeMirror.prototype = {
|
165
180
|
init: function() {
|
181
|
+
// Deprecated, but still supported.
|
166
182
|
if (this.options.initCallback) this.options.initCallback(this);
|
183
|
+
if (this.options.onLoad) this.options.onLoad(this);
|
167
184
|
if (this.options.lineNumbers) this.activateLineNumbers();
|
168
185
|
if (this.options.reindentOnLoad) this.reindent();
|
169
186
|
if (this.options.height == "dynamic") this.setDynamicHeight();
|
@@ -177,7 +194,8 @@ var CodeMirror = (function(){
|
|
177
194
|
|
178
195
|
focusIfIE: function() {
|
179
196
|
// in IE, a lot of selection-related functionality only works when the frame is focused
|
180
|
-
if (this.win.select.ie_selection
|
197
|
+
if (this.win.select.ie_selection && document.activeElement != this.frame)
|
198
|
+
this.focus();
|
181
199
|
},
|
182
200
|
focus: function() {
|
183
201
|
this.win.focus();
|
@@ -257,12 +275,12 @@ var CodeMirror = (function(){
|
|
257
275
|
setEnterMode: function(mode) {this.options.enterMode = mode;},
|
258
276
|
setLineNumbers: function(on) {
|
259
277
|
if (on && !this.lineNumbers) {
|
260
|
-
this.lineNumbers = addLineNumberDiv(this.wrapping);
|
278
|
+
this.lineNumbers = addLineNumberDiv(this.wrapping,this.options.firstLineNumber);
|
261
279
|
this.activateLineNumbers();
|
262
280
|
}
|
263
281
|
else if (!on && this.lineNumbers) {
|
264
282
|
this.wrapping.removeChild(this.lineNumbers);
|
265
|
-
this.wrapping.style.
|
283
|
+
this.wrapping.style.paddingLeft = "";
|
266
284
|
this.lineNumbers = null;
|
267
285
|
}
|
268
286
|
},
|
@@ -312,6 +330,15 @@ var CodeMirror = (function(){
|
|
312
330
|
nums = this.lineNumbers, scroller = nums.firstChild, self = this;
|
313
331
|
var barWidth = null;
|
314
332
|
|
333
|
+
nums.onclick = function(e) {
|
334
|
+
var handler = self.options.onLineNumberClick;
|
335
|
+
if (handler) {
|
336
|
+
var div = (e || window.event).target || (e || window.event).srcElement;
|
337
|
+
var num = div == nums ? NaN : Number(div.innerHTML);
|
338
|
+
if (!isNaN(num)) handler(num, div);
|
339
|
+
}
|
340
|
+
};
|
341
|
+
|
315
342
|
function sizeBar() {
|
316
343
|
if (frame.offsetWidth == 0) return;
|
317
344
|
for (var root = frame; root.parentNode; root = root.parentNode){}
|
@@ -341,7 +368,7 @@ var CodeMirror = (function(){
|
|
341
368
|
var targetHeight = 50 + Math.max(body.offsetHeight, Math.max(frame.offsetHeight, body.scrollHeight || 0)),
|
342
369
|
lastNumber = Math.ceil(targetHeight / lineHeight);
|
343
370
|
for (var i = scroller.childNodes.length; i <= lastNumber; i++) {
|
344
|
-
var div =
|
371
|
+
var div = createHTMLElement("div");
|
345
372
|
div.appendChild(document.createTextNode(fill ? String(i + self.options.firstLineNumber) : "\u00a0"));
|
346
373
|
scroller.appendChild(div);
|
347
374
|
}
|
@@ -368,7 +395,7 @@ var CodeMirror = (function(){
|
|
368
395
|
function setNum(n, node) {
|
369
396
|
// Does not typically happen (but can, if you mess with the
|
370
397
|
// document during the numbering)
|
371
|
-
if (!lineNum) lineNum = scroller.appendChild(
|
398
|
+
if (!lineNum) lineNum = scroller.appendChild(createHTMLElement("div"));
|
372
399
|
if (styleNums) styleNums(lineNum, node, n);
|
373
400
|
// Changes are accumulated, so that the document layout
|
374
401
|
// doesn't have to be recomputed during the pass
|
@@ -389,7 +416,11 @@ var CodeMirror = (function(){
|
|
389
416
|
setNum(next++, node.previousSibling);
|
390
417
|
for (; node && !win.isBR(node); node = node.nextSibling) {
|
391
418
|
var bott = node.offsetTop + node.offsetHeight;
|
392
|
-
while (scroller.offsetHeight && bott - 3 > pos)
|
419
|
+
while (scroller.offsetHeight && bott - 3 > pos) {
|
420
|
+
var oldPos = pos;
|
421
|
+
setNum(" ");
|
422
|
+
if (pos <= oldPos) break;
|
423
|
+
}
|
393
424
|
}
|
394
425
|
if (node) node = node.nextSibling;
|
395
426
|
if (new Date().getTime() > endTime) {
|
@@ -433,7 +464,7 @@ var CodeMirror = (function(){
|
|
433
464
|
},
|
434
465
|
|
435
466
|
setDynamicHeight: function() {
|
436
|
-
var self = this, activity = self.options.
|
467
|
+
var self = this, activity = self.options.onCursorActivity, win = self.win, body = win.document.body,
|
437
468
|
lineHeight = null, timeout = null, vmargin = 2 * self.frame.offsetTop;
|
438
469
|
body.style.overflowY = "hidden";
|
439
470
|
win.document.documentElement.style.overflowY = "hidden";
|
@@ -456,7 +487,7 @@ var CodeMirror = (function(){
|
|
456
487
|
self.wrapping.style.height = Math.max(vmargin + computedHeight, self.options.minHeight) + "px";
|
457
488
|
}
|
458
489
|
setTimeout(updateHeight, 300);
|
459
|
-
self.options.
|
490
|
+
self.options.onCursorActivity = function(x) {
|
460
491
|
if (activity) activity(x);
|
461
492
|
clearTimeout(timeout);
|
462
493
|
timeout = setTimeout(updateHeight, 100);
|
@@ -485,10 +516,10 @@ var CodeMirror = (function(){
|
|
485
516
|
options.height = area.style.height;
|
486
517
|
if (options.content == null) options.content = area.value;
|
487
518
|
|
519
|
+
function updateField() {
|
520
|
+
area.value = mirror.getCode();
|
521
|
+
}
|
488
522
|
if (area.form) {
|
489
|
-
function updateField() {
|
490
|
-
area.value = mirror.getCode();
|
491
|
-
}
|
492
523
|
if (typeof area.form.addEventListener == "function")
|
493
524
|
area.form.addEventListener("submit", updateField, false);
|
494
525
|
else
|
@@ -501,7 +532,7 @@ var CodeMirror = (function(){
|
|
501
532
|
area.form.submit();
|
502
533
|
area.form.submit = wrapSubmit;
|
503
534
|
}
|
504
|
-
area.form.submit = wrapSubmit;
|
535
|
+
try {area.form.submit = wrapSubmit;} catch(e){}
|
505
536
|
}
|
506
537
|
|
507
538
|
function insert(frame) {
|
@@ -513,11 +544,13 @@ var CodeMirror = (function(){
|
|
513
544
|
|
514
545
|
area.style.display = "none";
|
515
546
|
var mirror = new CodeMirror(insert, options);
|
547
|
+
mirror.save = updateField;
|
516
548
|
mirror.toTextArea = function() {
|
549
|
+
updateField();
|
517
550
|
area.parentNode.removeChild(mirror.wrapping);
|
518
551
|
area.style.display = "";
|
519
552
|
if (area.form) {
|
520
|
-
area.form.submit = realSubmit;
|
553
|
+
try {area.form.submit = realSubmit;} catch(e) {}
|
521
554
|
if (typeof area.form.removeEventListener == "function")
|
522
555
|
area.form.removeEventListener("submit", updateField, false);
|
523
556
|
else
|
@@ -533,7 +566,7 @@ var CodeMirror = (function(){
|
|
533
566
|
var match;
|
534
567
|
if (window.opera)
|
535
568
|
return Number(window.opera.version()) >= 9.52;
|
536
|
-
else if (/Apple
|
569
|
+
else if (/Apple Computer, Inc/.test(navigator.vendor) && (match = navigator.userAgent.match(/Version\/(\d+(?:\.\d+)?)\./)))
|
537
570
|
return Number(match[1]) >= 3;
|
538
571
|
else if (document.selection && window.ActiveXObject && (match = navigator.userAgent.match(/MSIE (\d+(?:\.\d*)?)\b/)))
|
539
572
|
return Number(match[1]) >= 6;
|