liquid_cms 0.2.0.11 → 0.2.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/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/pages/_list.html.erb +4 -4
- data/app/views/cms/shared/_sidebar.html.erb +32 -8
- data/app/views/layouts/cms.html.erb +5 -2
- data/generators/liquid_cms/templates/config/locales/cms/en.yml +3 -2
- data/generators/liquid_cms/templates/public/cms/codemirror/LICENSE +0 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/css/csscolors.css +0 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/css/docs.css +17 -3
- data/generators/liquid_cms/templates/public/cms/codemirror/css/font.js +15 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/css/jscolors.css +0 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/css/sparqlcolors.css +0 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/css/xmlcolors.css +0 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/js/codemirror.js +59 -26
- data/generators/liquid_cms/templates/public/cms/codemirror/js/editor.js +149 -71
- data/generators/liquid_cms/templates/public/cms/codemirror/js/highlight.js +2 -2
- data/generators/liquid_cms/templates/public/cms/codemirror/js/mirrorframe.js +2 -2
- data/generators/liquid_cms/templates/public/cms/codemirror/js/parsecss.js +5 -3
- data/generators/liquid_cms/templates/public/cms/codemirror/js/parsedummy.js +0 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/js/parsehtmlmixed.js +28 -9
- data/generators/liquid_cms/templates/public/cms/codemirror/js/parsejavascript.js +0 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/js/parsesparql.js +0 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/js/parsexml.js +6 -1
- data/generators/liquid_cms/templates/public/cms/codemirror/js/select.js +48 -21
- data/generators/liquid_cms/templates/public/cms/codemirror/js/stringstream.js +15 -1
- data/generators/liquid_cms/templates/public/cms/codemirror/js/tokenize.js +0 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/js/tokenizejavascript.js +1 -1
- data/generators/liquid_cms/templates/public/cms/codemirror/js/undo.js +17 -14
- data/generators/liquid_cms/templates/public/cms/codemirror/js/unittests.js +44 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/js/util.js +6 -3
- data/generators/liquid_cms/templates/public/cms/javascripts/cms.js +15 -1
- data/generators/liquid_cms/templates/public/cms/javascripts/livepipe.js +181 -0
- data/generators/liquid_cms/templates/public/cms/javascripts/tabs.js +149 -0
- data/generators/liquid_cms/templates/public/cms/stylesheets/ie9.css +4 -0
- data/generators/liquid_cms/templates/public/cms/stylesheets/sidebar.css +132 -0
- data/generators/liquid_cms/templates/public/cms/stylesheets/styles.css +1 -74
- data/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/functional/assets_controller_test.rb +3 -3
- data/test/rails_app/config/locales/cms/en.yml +8 -0
- metadata +11 -16
- data/generators/liquid_cms/templates/public/cms/codemirror/bigtest.html +0 -1296
- data/generators/liquid_cms/templates/public/cms/codemirror/css/people.jpg +0 -0
- data/generators/liquid_cms/templates/public/cms/codemirror/csstest.html +0 -60
- data/generators/liquid_cms/templates/public/cms/codemirror/highlight.html +0 -82
- data/generators/liquid_cms/templates/public/cms/codemirror/htmltest.html +0 -52
- data/generators/liquid_cms/templates/public/cms/codemirror/index.html +0 -245
- data/generators/liquid_cms/templates/public/cms/codemirror/jstest.html +0 -56
- data/generators/liquid_cms/templates/public/cms/codemirror/manual.html +0 -759
- data/generators/liquid_cms/templates/public/cms/codemirror/mixedtest.html +0 -52
- data/generators/liquid_cms/templates/public/cms/codemirror/sparqltest.html +0 -41
- data/generators/liquid_cms/templates/public/cms/codemirror/story.html +0 -671
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.
|
@@ -4,7 +4,7 @@ class Cms::MainController < Cms::SetupController
|
|
4
4
|
|
5
5
|
layout 'cms'
|
6
6
|
|
7
|
-
before_filter :
|
7
|
+
before_filter :load_resources
|
8
8
|
|
9
9
|
authenticate_user :all, :only => %w(index)
|
10
10
|
|
@@ -13,10 +13,11 @@ class Cms::MainController < Cms::SetupController
|
|
13
13
|
end
|
14
14
|
|
15
15
|
protected
|
16
|
-
def
|
16
|
+
def load_resources
|
17
17
|
@context = Cms::Context.new(@cms_context)
|
18
18
|
|
19
19
|
@pages = @context.pages.ordered.all(:conditions => {:layout_page_id => nil})
|
20
20
|
@assets = @context.assets.ordered
|
21
|
+
@components = @context.components
|
21
22
|
end
|
22
23
|
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
|
@@ -94,7 +102,6 @@ module Cms::CommonHelper
|
|
94
102
|
end
|
95
103
|
|
96
104
|
def asset_preview_option
|
97
|
-
|
98
|
-
ActiveSupport::JSON.decode(cookies[:__CJ_toggle] || '{}')['on'] == false ? 'style="display:none"' : ''
|
105
|
+
cookie_jar('toggle')['on'] == false ? 'style="display:none"' : ''
|
99
106
|
end
|
100
107
|
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,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,35 @@
|
|
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>
|
17
|
+
|
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_path %></p>
|
9
35
|
|
10
|
-
<hr style="border:1px solid #BBB" />
|
11
|
-
<p style="text-align:right"><%= cms_icon 'page.png' %> <%= link_to 'Documentation', cms_documentation_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' %>
|
8
|
-
<%= javascript_include_tag '/cms/javascripts/humanmsg', '/cms/javascripts/cookiejar', '/cms/javascripts/cms' %>
|
8
|
+
<%= javascript_include_tag '/cms/javascripts/humanmsg', '/cms/javascripts/cookiejar', '/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
|
</head>
|
18
21
|
<body id="cms" class="cms_<%= params[:controller].camelize.demodulize.downcase %>">
|
19
22
|
<div id="header">
|
@@ -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;
|