omf_web 1.2.5 → 1.2.6
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/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
|