omf_web 1.2.5 → 1.2.6
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/omf-web/content/content_proxy.rb +28 -15
- data/lib/omf-web/content/file_repository.rb +16 -57
- data/lib/omf-web/content/git_repository.rb +2 -121
- data/lib/omf-web/content/irods_repository.rb +2 -0
- data/lib/omf-web/content/repository.rb +121 -10
- data/lib/omf-web/content/static_repository.rb +3 -3
- data/lib/omf-web/rack/content_handler.rb +8 -6
- data/lib/omf-web/theme.rb +16 -2
- data/lib/omf-web/thin/logging.rb +13 -4
- data/lib/omf-web/version.rb +1 -1
- data/lib/omf-web/widget/text/maruku/output/to_html.rb +29 -23
- data/lib/omf-web/widget/text/maruku.rb +20 -5
- data/omf_web.gemspec +1 -1
- data/share/htdocs/graph/js/code_mirror.js +2 -1
- data/share/htdocs/vendor/VERSION_MAP.yaml +1 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/LICENSE-MIT +22 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/README.md +26 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/addons/bootstrap/jquery.smartmenus.bootstrap.css +103 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/addons/bootstrap/jquery.smartmenus.bootstrap.js +72 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/addons/bootstrap/jquery.smartmenus.bootstrap.min.js +3 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/addons/keyboard/jquery.smartmenus.keyboard.js +192 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/addons/keyboard/jquery.smartmenus.keyboard.min.js +3 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/css/sm-blue/css-gradients-fallback/current-item-bg.png +0 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/css/sm-blue/css-gradients-fallback/main-item-hover-bg.png +0 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/css/sm-blue/css-gradients-fallback/main-menu-bg.png +0 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/css/sm-blue/css-gradients-fallback/sub-item-hover-bg.png +0 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/css/sm-blue/css-gradients-fallback/vertical-main-item-bg.png +0 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/css/sm-blue/sm-blue.css +409 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/css/sm-clean/sm-clean.css +315 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/css/sm-core-css.css +23 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/css/sm-mint/sm-mint.css +320 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/css/sm-simple/sm-simple.css +218 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/jquery.smartmenus.js +1041 -0
- data/share/htdocs/vendor/smartmenus-0.9.6/jquery.smartmenus.min.js +3 -0
- metadata +218 -229
data/lib/omf-web/version.rb
CHANGED
@@ -467,7 +467,10 @@ It is copied as a standard HTML attribute.
|
|
467
467
|
dt.text = ' ';
|
468
468
|
p = wrap_as_element('p')
|
469
469
|
p.attributes['class'] = 'content'
|
470
|
-
[
|
470
|
+
p.attributes['line_no'] = Thread.current['maruku.line_no']
|
471
|
+
p.attributes['delegate'] = 'plan' # should most likely go into the js column handler
|
472
|
+
#[Text.new("\n"), p, dt, Text.new("\n")]
|
473
|
+
[Text.new("\n"), p, Text.new("\n")]
|
471
474
|
end
|
472
475
|
def to_html_ol; add_ws wrap_as_element('ol') end
|
473
476
|
def to_html_li; add_ws wrap_as_element('li') end
|
@@ -1013,25 +1016,28 @@ If true, raw HTML is discarded from the output.
|
|
1013
1016
|
" for object #{c.inspect[0,300]}"
|
1014
1017
|
end
|
1015
1018
|
|
1016
|
-
|
1017
|
-
if
|
1018
|
-
res.
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1019
|
+
unless (Thread.current['maruku_context'] || {})[:suppress_section]
|
1020
|
+
if method == 'to_html_header'
|
1021
|
+
if res.length > 1
|
1022
|
+
res.pop
|
1023
|
+
s = res[-1][-1]
|
1024
|
+
e.each do |el| s << el end
|
1025
|
+
e = res[-1]
|
1026
|
+
end
|
1027
|
+
|
1028
|
+
# Wrap into 'section' to more easily find back into MD from html
|
1029
|
+
e << (s = Element.new('section'))
|
1030
|
+
s.attributes['line_no'] = c.line_no
|
1031
|
+
s.attributes['level'] = c.level
|
1027
1032
|
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1033
|
+
toc = Thread.current['maruku.toc'] ||= []
|
1034
|
+
li = c.level - 1
|
1035
|
+
toc[li] = toc[li] ? (toc[li] + 1) : 1
|
1036
|
+
s.attributes['toc'] = toc.map {|l| l ? l : 1 }.join('.')
|
1032
1037
|
|
1033
|
-
|
1038
|
+
res << (e = [])
|
1034
1039
|
|
1040
|
+
end
|
1035
1041
|
end
|
1036
1042
|
|
1037
1043
|
if h.kind_of?Array
|
@@ -1042,12 +1048,12 @@ If true, raw HTML is discarded from the output.
|
|
1042
1048
|
# puts "LOOP ENDN res: #{res.inspect} -- e: #{e.inspect}"
|
1043
1049
|
end
|
1044
1050
|
# puts "after: #{res.inspect} e: #{e.inspect}"
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
+
if res.length > 1
|
1052
|
+
res.pop
|
1053
|
+
s = res[-1][-1]
|
1054
|
+
e.each do |el| s << el end
|
1055
|
+
e = res[-1]
|
1056
|
+
end
|
1051
1057
|
#puts e.inspect
|
1052
1058
|
e
|
1053
1059
|
end
|
@@ -5,6 +5,7 @@ require 'maruku'
|
|
5
5
|
require 'maruku/ext/math'
|
6
6
|
# Monkey patches to add line numbers to html output
|
7
7
|
|
8
|
+
require 'omf_base/lobject'
|
8
9
|
require 'omf_web'
|
9
10
|
require 'omf-web/widget/text/maruku/input/parse_block'
|
10
11
|
require 'omf-web/widget/text/maruku/output/to_html'
|
@@ -132,11 +133,25 @@ module OMF::Web::Widget::Text
|
|
132
133
|
end # OMF::Web::Widget::Text
|
133
134
|
|
134
135
|
if __FILE__ == $0
|
135
|
-
|
136
|
-
|
137
|
-
|
136
|
+
OMF::Base::Loggable.init_log 'maruku'
|
137
|
+
|
138
|
+
if fname = ARGV[0]
|
139
|
+
content = File.open(fname).read
|
140
|
+
else
|
141
|
+
content = %{
|
142
|
+
# Lorem ipsum dolor sit
|
143
|
+
|
144
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin
|
145
|
+
sollicitudin nibh eu ligula lobortis ornare. Sed nibh nibh,
|
146
|
+
ullamcorper at vehicula ac, molestie ac nunc.
|
147
|
+
|
148
|
+
## Cras ut volutpat magna
|
149
|
+
|
150
|
+
Duis sodales, nisi vel pellentesque imperdiet, nisi massa accumsan
|
151
|
+
lorem, gravida scelerisque velit est vitae eros. Suspendisse eu
|
152
|
+
lacinia elit.
|
153
|
+
}
|
138
154
|
end
|
139
|
-
content = File.open(fname).read
|
140
155
|
x = OMF::Web::Widget::Text::Maruku.format_content(content)
|
141
|
-
puts x.to_html
|
156
|
+
puts x.to_html(suppress_section: false)
|
142
157
|
end
|
data/omf_web.gemspec
CHANGED
@@ -30,7 +30,7 @@ Gem::Specification.new do |s|
|
|
30
30
|
s.add_runtime_dependency "maruku", "~> 0.6.0"
|
31
31
|
s.add_runtime_dependency "ritex", "~> 1.0.0"
|
32
32
|
s.add_runtime_dependency "json", "~> 1.7.0"
|
33
|
-
s.add_runtime_dependency "grit"
|
33
|
+
s.add_runtime_dependency "gitlab-grit"
|
34
34
|
s.add_runtime_dependency "websocket-rack", "~> 0.4.0"
|
35
35
|
s.add_runtime_dependency "rack-accept", "~> 0.4.0"
|
36
36
|
s.add_runtime_dependency "i18n"
|
@@ -47,6 +47,7 @@ define(["graph/abstract_widget"], function (abstract_widget) {
|
|
47
47
|
lineNumbers: true,
|
48
48
|
matchBrackets: true,
|
49
49
|
tabMode: "indent",
|
50
|
+
readOnly: (o.read_only == true),
|
50
51
|
onCursorActivity: function() {
|
51
52
|
// try to highlight active line
|
52
53
|
cm.setLineClass(hlLine, null, null);
|
@@ -123,4 +124,4 @@ define(["graph/abstract_widget"], function (abstract_widget) {
|
|
123
124
|
|
124
125
|
return code_mirror;
|
125
126
|
|
126
|
-
});
|
127
|
+
});
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Vasil Dinkov, Vadikom Web Ltd.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# SmartMenus
|
2
|
+
|
3
|
+
jQuery website menu plugin. Responsive and accessible list-based website menus that work on all devices.
|
4
|
+
Check out [the demo page](http://vadikom.github.io/smartmenus/src/demo/).
|
5
|
+
|
6
|
+
## Homepage
|
7
|
+
|
8
|
+
http://www.smartmenus.org/
|
9
|
+
|
10
|
+
## Download
|
11
|
+
|
12
|
+
Download the ZIP package which includes a basic demo:
|
13
|
+
|
14
|
+
http://www.smartmenus.org/download/
|
15
|
+
|
16
|
+
## Getting started and API documentation
|
17
|
+
|
18
|
+
http://www.smartmenus.org/docs/
|
19
|
+
|
20
|
+
## Bugs and issues
|
21
|
+
|
22
|
+
https://github.com/vadikom/smartmenus/issues
|
23
|
+
|
24
|
+
## Support forums
|
25
|
+
|
26
|
+
http://www.smartmenus.org/support/forums/
|
@@ -0,0 +1,103 @@
|
|
1
|
+
/*
|
2
|
+
You probably do not need to edit this at all.
|
3
|
+
|
4
|
+
Add some SmartMenus required styles not covered in Bootstrap 3's default CSS.
|
5
|
+
These are theme independent and should work with any Bootstrap 3 theme mod.
|
6
|
+
*/
|
7
|
+
/* sub menus arrows */
|
8
|
+
.navbar-nav .sub-arrow, .navbar-nav .collapsible .sub-arrow {
|
9
|
+
position:static;
|
10
|
+
margin-top:0;
|
11
|
+
margin-right:0;
|
12
|
+
margin-left:6px;
|
13
|
+
display:inline-block;
|
14
|
+
width:0;
|
15
|
+
height:0;
|
16
|
+
overflow:hidden;
|
17
|
+
vertical-align:middle;
|
18
|
+
border-top:4px solid;
|
19
|
+
border-right:4px dashed transparent;
|
20
|
+
border-bottom:4px dashed transparent;
|
21
|
+
border-left:4px dashed transparent;
|
22
|
+
}
|
23
|
+
.navbar-fixed-bottom .sub-arrow {
|
24
|
+
margin-top:-5px;
|
25
|
+
border-top:4px dashed transparent;
|
26
|
+
border-bottom:4px solid;
|
27
|
+
}
|
28
|
+
.navbar-nav ul .sub-arrow {
|
29
|
+
position:absolute;
|
30
|
+
right:0;
|
31
|
+
margin-top:6px;
|
32
|
+
margin-right:15px;
|
33
|
+
border-top:4px dashed transparent;
|
34
|
+
border-bottom:4px dashed transparent;
|
35
|
+
border-left:4px solid;
|
36
|
+
}
|
37
|
+
.navbar-nav ul a.has-submenu {
|
38
|
+
padding-right:30px;
|
39
|
+
}
|
40
|
+
/* scrolling arrows for tall menus */
|
41
|
+
.navbar-nav span.scroll-up, .navbar-nav span.scroll-down {
|
42
|
+
position:absolute;
|
43
|
+
display:none;
|
44
|
+
visibility:hidden;
|
45
|
+
height:20px;
|
46
|
+
overflow:hidden;
|
47
|
+
text-align:center;
|
48
|
+
}
|
49
|
+
.navbar-nav span.scroll-up-arrow, .navbar-nav span.scroll-down-arrow {
|
50
|
+
position:absolute;
|
51
|
+
top:-2px;
|
52
|
+
left:50%;
|
53
|
+
margin-left:-8px;
|
54
|
+
width:0;
|
55
|
+
height:0;
|
56
|
+
overflow:hidden;
|
57
|
+
border-top:7px dashed transparent;
|
58
|
+
border-right:7px dashed transparent;
|
59
|
+
border-bottom:7px solid;
|
60
|
+
border-left:7px dashed transparent;
|
61
|
+
}
|
62
|
+
.navbar-nav span.scroll-down-arrow {
|
63
|
+
top:6px;
|
64
|
+
border-top:7px solid;
|
65
|
+
border-right:7px dashed transparent;
|
66
|
+
border-bottom:7px dashed transparent;
|
67
|
+
border-left:7px dashed transparent;
|
68
|
+
}
|
69
|
+
/* add more indentation for 2+ level sub in collapsible mode - Bootstrap normally supports just 1 level sub menus */
|
70
|
+
.navbar-nav .collapsible ul .dropdown-menu > li > a,
|
71
|
+
.navbar-nav .collapsible ul .dropdown-menu .dropdown-header {
|
72
|
+
padding-left:35px;
|
73
|
+
}
|
74
|
+
.navbar-nav .collapsible ul ul .dropdown-menu > li > a,
|
75
|
+
.navbar-nav .collapsible ul ul .dropdown-menu .dropdown-header {
|
76
|
+
padding-left:45px;
|
77
|
+
}
|
78
|
+
.navbar-nav .collapsible ul ul ul .dropdown-menu > li > a,
|
79
|
+
.navbar-nav .collapsible ul ul ul .dropdown-menu .dropdown-header {
|
80
|
+
padding-left:55px;
|
81
|
+
}
|
82
|
+
.navbar-nav .collapsible ul ul ul ul .dropdown-menu > li > a,
|
83
|
+
.navbar-nav .collapsible ul ul ul ul .dropdown-menu .dropdown-header {
|
84
|
+
padding-left:65px;
|
85
|
+
}
|
86
|
+
/* fix SmartMenus sub menus auto width (subMenusMinWidth and subMenusMaxWidth options) */
|
87
|
+
.navbar-nav .dropdown-menu > li > a {
|
88
|
+
white-space:normal;
|
89
|
+
}
|
90
|
+
.navbar-nav ul.sm-nowrap > li > a {
|
91
|
+
white-space:nowrap;
|
92
|
+
}
|
93
|
+
/* fix .navbar-right subs alignment */
|
94
|
+
.navbar-right ul.dropdown-menu {
|
95
|
+
left:0;
|
96
|
+
right:auto;
|
97
|
+
}
|
98
|
+
/* The following will make the sub menus collapsible for small screen devices (it's not recommended editing these) */
|
99
|
+
.navbar-nav .collapsible ul {display:none;position:static !important;top:auto !important;left:auto !important;margin-left:0 !important;margin-top:0 !important;width:auto !important;min-width:0 !important;max-width:none !important;}
|
100
|
+
.navbar-nav .collapsible ul.sm-nowrap > li > a {white-space:normal;}
|
101
|
+
.navbar-nav .collapsible iframe{display:none;}
|
102
|
+
/* disable Bootstrap 3's global box-sizing:border-box; for the menus as it doesn't play nice with SmartMenus */
|
103
|
+
ul.sm li *,ul.sm li *:before,ul.sm li *:after{-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}
|
@@ -0,0 +1,72 @@
|
|
1
|
+
/*!
|
2
|
+
* SmartMenus jQuery Plugin Bootstrap Addon - v0.1.0 - March 27, 2014
|
3
|
+
* http://www.smartmenus.org/
|
4
|
+
*
|
5
|
+
* Copyright 2014 Vasil Dinkov, Vadikom Web Ltd.
|
6
|
+
* http://vadikom.com
|
7
|
+
*
|
8
|
+
* Licensed MIT
|
9
|
+
*/
|
10
|
+
|
11
|
+
(function($) {
|
12
|
+
|
13
|
+
// init ondomready
|
14
|
+
$(function() {
|
15
|
+
|
16
|
+
// init all menus
|
17
|
+
$('ul.navbar-nav').each(function() {
|
18
|
+
var $this = $(this);
|
19
|
+
$this.addClass('sm').smartmenus({
|
20
|
+
|
21
|
+
// these are some good default options that should work for all
|
22
|
+
// you can, of course, tweak these as you like
|
23
|
+
subMenusSubOffsetX: 2,
|
24
|
+
subMenusSubOffsetY: -6,
|
25
|
+
subIndicatorsPos: 'append',
|
26
|
+
subIndicatorsText: '...',
|
27
|
+
collapsibleShowFunction: null,
|
28
|
+
collapsibleHideFunction: null,
|
29
|
+
rightToLeftSubMenus: $this.hasClass('navbar-right'),
|
30
|
+
bottomToTopSubMenus: $this.closest('.navbar').hasClass('navbar-fixed-bottom')
|
31
|
+
})
|
32
|
+
// set Bootstrap's "active" class to SmartMenus "current" items (should someone decide to enable markCurrentItem: true)
|
33
|
+
.find('a.current').parent().addClass('active');
|
34
|
+
})
|
35
|
+
.bind({
|
36
|
+
// set/unset proper Bootstrap classes for some menu elements
|
37
|
+
'show.smapi': function(e, menu) {
|
38
|
+
var $menu = $(menu),
|
39
|
+
$scrollArrows = $menu.dataSM('scroll-arrows'),
|
40
|
+
obj = $(this).data('smartmenus');
|
41
|
+
if ($scrollArrows) {
|
42
|
+
// they inherit border-color from body, so we can use its background-color too
|
43
|
+
$scrollArrows.css('background-color', $(document.body).css('background-color'));
|
44
|
+
}
|
45
|
+
$menu.parent().addClass('open' + (obj.isCollapsible() ? ' collapsible' : ''));
|
46
|
+
},
|
47
|
+
'hide.smapi': function(e, menu) {
|
48
|
+
$(menu).parent().removeClass('open collapsible');
|
49
|
+
},
|
50
|
+
// click the parent item to toggle the sub menus (and reset deeper levels and other branches on click)
|
51
|
+
'click.smapi': function(e, item) {
|
52
|
+
var obj = $(this).data('smartmenus');
|
53
|
+
if (obj.isCollapsible()) {
|
54
|
+
var $item = $(item),
|
55
|
+
$sub = $item.parent().dataSM('sub');
|
56
|
+
if ($sub && $sub.dataSM('shown-before') && $sub.is(':visible')) {
|
57
|
+
obj.itemActivate($item);
|
58
|
+
obj.menuHide($sub);
|
59
|
+
return false;
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}
|
63
|
+
});
|
64
|
+
|
65
|
+
});
|
66
|
+
|
67
|
+
// fix collapsible menu detection for Bootstrap 3
|
68
|
+
$.SmartMenus.prototype.isCollapsible = function() {
|
69
|
+
return this.$firstLink.parent().css('float') != 'left';
|
70
|
+
};
|
71
|
+
|
72
|
+
})(jQuery);
|
@@ -0,0 +1,3 @@
|
|
1
|
+
/*! SmartMenus jQuery Plugin Bootstrap Addon - v0.1.0 - March 27, 2014
|
2
|
+
* http://www.smartmenus.org/
|
3
|
+
* Copyright 2014 Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){t(function(){t("ul.navbar-nav").each(function(){var s=t(this);s.addClass("sm").smartmenus({subMenusSubOffsetX:2,subMenusSubOffsetY:-6,subIndicatorsPos:"append",subIndicatorsText:"...",collapsibleShowFunction:null,collapsibleHideFunction:null,rightToLeftSubMenus:s.hasClass("navbar-right"),bottomToTopSubMenus:s.closest(".navbar").hasClass("navbar-fixed-bottom")}).find("a.current").parent().addClass("active")}).bind({"show.smapi":function(s,e){var i=t(e),o=i.dataSM("scroll-arrows"),a=t(this).data("smartmenus");o&&o.css("background-color",t(document.body).css("background-color")),i.parent().addClass("open"+(a.isCollapsible()?" collapsible":""))},"hide.smapi":function(s,e){t(e).parent().removeClass("open collapsible")},"click.smapi":function(s,e){var i=t(this).data("smartmenus");if(i.isCollapsible()){var o=t(e),a=o.parent().dataSM("sub");if(a&&a.dataSM("shown-before")&&a.is(":visible"))return i.itemActivate(o),i.menuHide(a),!1}}})}),t.SmartMenus.prototype.isCollapsible=function(){return"left"!=this.$firstLink.parent().css("float")}})(jQuery);
|
@@ -0,0 +1,192 @@
|
|
1
|
+
/*!
|
2
|
+
* SmartMenus jQuery Plugin Keyboard Addon - v0.1.0 - March 27, 2014
|
3
|
+
* http://www.smartmenus.org/
|
4
|
+
*
|
5
|
+
* Copyright 2014 Vasil Dinkov, Vadikom Web Ltd.
|
6
|
+
* http://vadikom.com
|
7
|
+
*
|
8
|
+
* Licensed MIT
|
9
|
+
*/
|
10
|
+
|
11
|
+
(function($) {
|
12
|
+
|
13
|
+
function getFirstItemLink($ul) {
|
14
|
+
return $ul.find('> li > a:not(.disabled)').eq(0);
|
15
|
+
}
|
16
|
+
function getLastItemLink($ul) {
|
17
|
+
return $ul.find('> li > a:not(.disabled)').eq(-1);
|
18
|
+
}
|
19
|
+
function getNextItemLink($li, noLoop) {
|
20
|
+
var $a = $li.nextAll('li').children('a:not(.disabled)').eq(0);
|
21
|
+
return noLoop || $a.length ? $a : getFirstItemLink($li.parent());
|
22
|
+
}
|
23
|
+
function getPreviousItemLink($li, noLoop) {
|
24
|
+
var $a = $li.prevAll('li').children('a:not(.disabled)').eq(0);
|
25
|
+
return noLoop || $a.length ? $a : getLastItemLink($li.parent());
|
26
|
+
}
|
27
|
+
|
28
|
+
// jQuery's .focus() is unreliable in some versions, so we're going to call the links' native JS focus method
|
29
|
+
$.fn.focusSM = function() {
|
30
|
+
if (this.length && this[0].focus) {
|
31
|
+
this[0].focus();
|
32
|
+
}
|
33
|
+
return this;
|
34
|
+
}
|
35
|
+
|
36
|
+
$.extend($.SmartMenus.Keyboard = {}, {
|
37
|
+
docKeydown: function(e) {
|
38
|
+
var keyCode = e.keyCode;
|
39
|
+
if (!/(27|37|38|39|40)/.test(keyCode)) {
|
40
|
+
return;
|
41
|
+
}
|
42
|
+
var $root = $(this),
|
43
|
+
obj = $root.data('smartmenus'),
|
44
|
+
$target = $(e.target);
|
45
|
+
if (!obj || !$target.is('a')) {
|
46
|
+
return;
|
47
|
+
}
|
48
|
+
var $li = $target.parent(),
|
49
|
+
$ul = $li.parent(),
|
50
|
+
level = $ul.dataSM('level');
|
51
|
+
// exit it if this is an A inside a mega drop-down
|
52
|
+
if (!level) {
|
53
|
+
return;
|
54
|
+
}
|
55
|
+
// swap left & right keys
|
56
|
+
if (obj.opts.rightToLeftSubMenus) {
|
57
|
+
if (keyCode == 37) {
|
58
|
+
keyCode = 39;
|
59
|
+
} else if (keyCode == 39) {
|
60
|
+
keyCode = 37;
|
61
|
+
}
|
62
|
+
}
|
63
|
+
switch (keyCode) {
|
64
|
+
case 27: // Esc
|
65
|
+
if (obj.visibleSubMenus[level]) {
|
66
|
+
obj.menuHide(obj.visibleSubMenus[level]);
|
67
|
+
} else if (level == 1) {
|
68
|
+
if (obj.opts.isPopup) {
|
69
|
+
obj.menuHideAll();
|
70
|
+
}
|
71
|
+
if (obj.opts.keyboardEscapeFocus) {
|
72
|
+
try { obj.opts.keyboardEscapeFocus.focusSM(); } catch(e) {};
|
73
|
+
// focus next focusable page element
|
74
|
+
} else {
|
75
|
+
var $lastMenuFocusable = $root.find('a, input, select, button, textarea').eq(-1),
|
76
|
+
$allFocusables = $('a, input, select, button, textarea'),
|
77
|
+
nextFocusableIndex = $allFocusables.index($lastMenuFocusable[0]) + 1;
|
78
|
+
$allFocusables.eq(nextFocusableIndex).focusSM();
|
79
|
+
}
|
80
|
+
} else {
|
81
|
+
$ul.dataSM('parent-a').focusSM();
|
82
|
+
obj.menuHide(obj.visibleSubMenus[level - 1]);
|
83
|
+
}
|
84
|
+
break;
|
85
|
+
case 37: // Left
|
86
|
+
if (obj.isCollapsible()) {
|
87
|
+
break;
|
88
|
+
}
|
89
|
+
if (level > 2 || level == 2 && $root.hasClass('sm-vertical')) {
|
90
|
+
obj.activatedItems[level - 2].focusSM();
|
91
|
+
// move to previous non-disabled parent item (make sure we cycle so it might be the last item)
|
92
|
+
} else if (!$root.hasClass('sm-vertical')) {
|
93
|
+
getPreviousItemLink(obj.activatedItems[0].parent()).focusSM();
|
94
|
+
}
|
95
|
+
break;
|
96
|
+
case 38: // Up
|
97
|
+
if (obj.isCollapsible()) {
|
98
|
+
var $firstItem;
|
99
|
+
// if this is the first item of a sub menu, move to the parent item
|
100
|
+
if (level > 1 && ($firstItem = getFirstItemLink($ul)).length && $target[0] == $firstItem[0]) {
|
101
|
+
obj.activatedItems[level - 2].focusSM();
|
102
|
+
} else {
|
103
|
+
getPreviousItemLink($li).focusSM();
|
104
|
+
}
|
105
|
+
} else {
|
106
|
+
if (level == 1 && !$root.hasClass('sm-vertical') && obj.visibleSubMenus[level] && obj.opts.bottomToTopSubMenus) {
|
107
|
+
getLastItemLink(obj.visibleSubMenus[level]).focusSM();
|
108
|
+
} else if (level > 1 || $root.hasClass('sm-vertical')) {
|
109
|
+
getPreviousItemLink($li).focusSM();
|
110
|
+
}
|
111
|
+
}
|
112
|
+
break;
|
113
|
+
case 39: // Right
|
114
|
+
if (obj.isCollapsible()) {
|
115
|
+
break;
|
116
|
+
}
|
117
|
+
// move to next non-disabled parent item (make sure we cycle so it might be the last item)
|
118
|
+
if ((level == 1 || !obj.visibleSubMenus[level]) && !$root.hasClass('sm-vertical')) {
|
119
|
+
getNextItemLink(obj.activatedItems[0].parent()).focusSM();
|
120
|
+
} else if (obj.visibleSubMenus[level] && !obj.visibleSubMenus[level].hasClass('mega-menu')) {
|
121
|
+
getFirstItemLink(obj.visibleSubMenus[level]).focusSM();
|
122
|
+
}
|
123
|
+
break;
|
124
|
+
case 40: // Down
|
125
|
+
if (obj.isCollapsible()) {
|
126
|
+
var $firstSubItem,
|
127
|
+
$lastItem;
|
128
|
+
// move to sub menu if appropriate
|
129
|
+
if (obj.visibleSubMenus[level] && !obj.visibleSubMenus[level].hasClass('mega-menu') && ($firstSubItem = getFirstItemLink(obj.visibleSubMenus[level])).length) {
|
130
|
+
$firstSubItem.focusSM();
|
131
|
+
// if this is the last item of a sub menu, move to the next parent item
|
132
|
+
} else if (level > 1 && ($lastItem = getLastItemLink($ul)).length && $target[0] == $lastItem[0]) {
|
133
|
+
var $parentItem = obj.activatedItems[level - 2].parent(),
|
134
|
+
$nextParentItem = null;
|
135
|
+
while ($parentItem.is('li')) {
|
136
|
+
if (($nextParentItem = getNextItemLink($parentItem, true)).length) {
|
137
|
+
break;
|
138
|
+
}
|
139
|
+
$parentItem = $parentItem.parent().parent();
|
140
|
+
}
|
141
|
+
$nextParentItem.focusSM();
|
142
|
+
} else {
|
143
|
+
getNextItemLink($li).focusSM();
|
144
|
+
}
|
145
|
+
} else {
|
146
|
+
if (level == 1 && !$root.hasClass('sm-vertical') && obj.visibleSubMenus[level] && !obj.opts.bottomToTopSubMenus) {
|
147
|
+
getFirstItemLink(obj.visibleSubMenus[level]).focusSM();
|
148
|
+
} else if (level > 1 || $root.hasClass('sm-vertical')) {
|
149
|
+
getNextItemLink($li).focusSM();
|
150
|
+
}
|
151
|
+
}
|
152
|
+
break;
|
153
|
+
}
|
154
|
+
e.stopPropagation();
|
155
|
+
e.preventDefault();
|
156
|
+
}
|
157
|
+
});
|
158
|
+
|
159
|
+
// hook it
|
160
|
+
$(document).delegate('ul.sm', 'keydown.smartmenus', $.SmartMenus.Keyboard.docKeydown);
|
161
|
+
|
162
|
+
$.extend($.SmartMenus.prototype, {
|
163
|
+
keyboardSetEscapeFocus: function($elm) {
|
164
|
+
this.opts.keyboardEscapeFocus = $elm;
|
165
|
+
},
|
166
|
+
keyboardSetHotkey: function(keyCode, modifiers) {
|
167
|
+
var self = this;
|
168
|
+
$(document).bind('keydown.smartmenus' + this.rootId, function(e) {
|
169
|
+
if (keyCode == e.keyCode) {
|
170
|
+
var procede = true;
|
171
|
+
if (modifiers) {
|
172
|
+
if (typeof modifiers == 'string') {
|
173
|
+
modifiers = [modifiers];
|
174
|
+
}
|
175
|
+
$.each(['ctrlKey', 'shiftKey', 'altKey', 'metaKey'], function(index, value) {
|
176
|
+
if ($.inArray(value, modifiers) >= 0 && !e[value] || $.inArray(value, modifiers) < 0 && e[value]) {
|
177
|
+
procede = false;
|
178
|
+
return false;
|
179
|
+
}
|
180
|
+
});
|
181
|
+
}
|
182
|
+
if (procede) {
|
183
|
+
getFirstItemLink(self.$root).focusSM();
|
184
|
+
e.stopPropagation();
|
185
|
+
e.preventDefault();
|
186
|
+
}
|
187
|
+
}
|
188
|
+
});
|
189
|
+
}
|
190
|
+
});
|
191
|
+
|
192
|
+
})(jQuery);
|
@@ -0,0 +1,3 @@
|
|
1
|
+
/*! SmartMenus jQuery Plugin Keyboard Addon - v0.1.0 - March 27, 2014
|
2
|
+
* http://www.smartmenus.org/
|
3
|
+
* Copyright 2014 Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){function s(t){return t.find("> li > a:not(.disabled)").eq(0)}function e(t){return t.find("> li > a:not(.disabled)").eq(-1)}function i(t,e){var i=t.nextAll("li").children("a:not(.disabled)").eq(0);return e||i.length?i:s(t.parent())}function o(t,s){var i=t.prevAll("li").children("a:not(.disabled)").eq(0);return s||i.length?i:e(t.parent())}t.fn.focusSM=function(){return this.length&&this[0].focus&&this[0].focus(),this},t.extend(t.SmartMenus.Keyboard={},{docKeydown:function(a){var n=a.keyCode;if(/(27|37|38|39|40)/.test(n)){var r=t(this),h=r.data("smartmenus"),u=t(a.target);if(h&&u.is("a")){var l=u.parent(),d=l.parent(),c=d.dataSM("level");if(c){switch(h.opts.rightToLeftSubMenus&&(37==n?n=39:39==n&&(n=37)),n){case 27:if(h.visibleSubMenus[c])h.menuHide(h.visibleSubMenus[c]);else if(1==c)if(h.opts.isPopup&&h.menuHideAll(),h.opts.keyboardEscapeFocus)try{h.opts.keyboardEscapeFocus.focusSM()}catch(a){}else{var m=r.find("a, input, select, button, textarea").eq(-1),p=t("a, input, select, button, textarea"),f=p.index(m[0])+1;p.eq(f).focusSM()}else d.dataSM("parent-a").focusSM(),h.menuHide(h.visibleSubMenus[c-1]);break;case 37:if(h.isCollapsible())break;c>2||2==c&&r.hasClass("sm-vertical")?h.activatedItems[c-2].focusSM():r.hasClass("sm-vertical")||o(h.activatedItems[0].parent()).focusSM();break;case 38:if(h.isCollapsible()){var v;c>1&&(v=s(d)).length&&u[0]==v[0]?h.activatedItems[c-2].focusSM():o(l).focusSM()}else 1==c&&!r.hasClass("sm-vertical")&&h.visibleSubMenus[c]&&h.opts.bottomToTopSubMenus?e(h.visibleSubMenus[c]).focusSM():(c>1||r.hasClass("sm-vertical"))&&o(l).focusSM();break;case 39:if(h.isCollapsible())break;1!=c&&h.visibleSubMenus[c]||r.hasClass("sm-vertical")?h.visibleSubMenus[c]&&!h.visibleSubMenus[c].hasClass("mega-menu")&&s(h.visibleSubMenus[c]).focusSM():i(h.activatedItems[0].parent()).focusSM();break;case 40:if(h.isCollapsible()){var b,M;if(h.visibleSubMenus[c]&&!h.visibleSubMenus[c].hasClass("mega-menu")&&(b=s(h.visibleSubMenus[c])).length)b.focusSM();else if(c>1&&(M=e(d)).length&&u[0]==M[0]){for(var S=h.activatedItems[c-2].parent(),w=null;S.is("li")&&!(w=i(S,!0)).length;)S=S.parent().parent();w.focusSM()}else i(l).focusSM()}else 1!=c||r.hasClass("sm-vertical")||!h.visibleSubMenus[c]||h.opts.bottomToTopSubMenus?(c>1||r.hasClass("sm-vertical"))&&i(l).focusSM():s(h.visibleSubMenus[c]).focusSM()}a.stopPropagation(),a.preventDefault()}}}}}),t(document).delegate("ul.sm","keydown.smartmenus",t.SmartMenus.Keyboard.docKeydown),t.extend(t.SmartMenus.prototype,{keyboardSetEscapeFocus:function(t){this.opts.keyboardEscapeFocus=t},keyboardSetHotkey:function(e,i){var o=this;t(document).bind("keydown.smartmenus"+this.rootId,function(a){if(e==a.keyCode){var n=!0;i&&("string"==typeof i&&(i=[i]),t.each(["ctrlKey","shiftKey","altKey","metaKey"],function(s,e){return t.inArray(e,i)>=0&&!a[e]||0>t.inArray(e,i)&&a[e]?(n=!1,!1):void 0})),n&&(s(o.$root).focusSM(),a.stopPropagation(),a.preventDefault())}})}})})(jQuery);
|
data/share/htdocs/vendor/smartmenus-0.9.6/css/sm-blue/css-gradients-fallback/current-item-bg.png
ADDED
Binary file
|
data/share/htdocs/vendor/smartmenus-0.9.6/css/sm-blue/css-gradients-fallback/main-item-hover-bg.png
ADDED
Binary file
|
Binary file
|