goncalossilva-showoff 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +473 -0
  3. data/Rakefile +7 -0
  4. data/bin/showoff +136 -0
  5. data/lib/princely.rb +84 -0
  6. data/lib/showoff.rb +418 -0
  7. data/lib/showoff_utils.rb +361 -0
  8. data/public/css/fg.menu.css +114 -0
  9. data/public/css/onepage.css +60 -0
  10. data/public/css/pdf.css +12 -0
  11. data/public/css/reset.css +53 -0
  12. data/public/css/sh_style.css +66 -0
  13. data/public/css/showoff.css +350 -0
  14. data/public/css/spinner_bar.gif +0 -0
  15. data/public/css/theme/images/ui-bg_diagonals-small_100_f0efea_40x40.png +0 -0
  16. data/public/css/theme/images/ui-bg_flat_35_f0f0f0_40x100.png +0 -0
  17. data/public/css/theme/images/ui-bg_glass_55_fcf0ba_1x400.png +0 -0
  18. data/public/css/theme/images/ui-bg_glow-ball_25_2e2e28_600x600.png +0 -0
  19. data/public/css/theme/images/ui-bg_highlight-soft_100_f0efea_1x100.png +0 -0
  20. data/public/css/theme/images/ui-bg_highlight-soft_25_327E04_1x100.png +0 -0
  21. data/public/css/theme/images/ui-bg_highlight-soft_25_5A9D1A_1x100.png +0 -0
  22. data/public/css/theme/images/ui-bg_highlight-soft_95_ffedad_1x100.png +0 -0
  23. data/public/css/theme/images/ui-bg_inset-soft_22_3b3b35_1x100.png +0 -0
  24. data/public/css/theme/images/ui-icons_808080_256x240.png +0 -0
  25. data/public/css/theme/images/ui-icons_8DC262_256x240.png +0 -0
  26. data/public/css/theme/images/ui-icons_cd0a0a_256x240.png +0 -0
  27. data/public/css/theme/images/ui-icons_e7e6e4_256x240.png +0 -0
  28. data/public/css/theme/images/ui-icons_eeeeee_256x240.png +0 -0
  29. data/public/css/theme/images/ui-icons_ffffff_256x240.png +0 -0
  30. data/public/css/theme/ui.accordion.css +9 -0
  31. data/public/css/theme/ui.all.css +2 -0
  32. data/public/css/theme/ui.base.css +9 -0
  33. data/public/css/theme/ui.core.css +37 -0
  34. data/public/css/theme/ui.datepicker.css +62 -0
  35. data/public/css/theme/ui.dialog.css +13 -0
  36. data/public/css/theme/ui.progressbar.css +4 -0
  37. data/public/css/theme/ui.resizable.css +13 -0
  38. data/public/css/theme/ui.slider.css +17 -0
  39. data/public/css/theme/ui.tabs.css +9 -0
  40. data/public/css/theme/ui.theme.css +245 -0
  41. data/public/favicon.ico +0 -0
  42. data/public/js/core.js +79 -0
  43. data/public/js/fg.menu.js +645 -0
  44. data/public/js/jTypeWriter.js +26 -0
  45. data/public/js/jquery-1.4.2.min.js +154 -0
  46. data/public/js/jquery-print.js +109 -0
  47. data/public/js/jquery.batchImageLoad.js +56 -0
  48. data/public/js/jquery.cookie.js +96 -0
  49. data/public/js/jquery.cycle.all.js +1284 -0
  50. data/public/js/jquery.doubletap-0.1.js +105 -0
  51. data/public/js/jquery.uuid.js +24 -0
  52. data/public/js/jquery.ws-0.3pre.js +201 -0
  53. data/public/js/onepage.js +5 -0
  54. data/public/js/sh_lang/sh_bison.min.js +1 -0
  55. data/public/js/sh_lang/sh_c.min.js +1 -0
  56. data/public/js/sh_lang/sh_caml.min.js +1 -0
  57. data/public/js/sh_lang/sh_changelog.min.js +1 -0
  58. data/public/js/sh_lang/sh_cpp.min.js +1 -0
  59. data/public/js/sh_lang/sh_csharp.min.js +1 -0
  60. data/public/js/sh_lang/sh_css.min.js +1 -0
  61. data/public/js/sh_lang/sh_cucumber.min.js +2 -0
  62. data/public/js/sh_lang/sh_desktop.min.js +1 -0
  63. data/public/js/sh_lang/sh_diff.min.js +1 -0
  64. data/public/js/sh_lang/sh_flex.min.js +1 -0
  65. data/public/js/sh_lang/sh_glsl.min.js +1 -0
  66. data/public/js/sh_lang/sh_haxe.min.js +1 -0
  67. data/public/js/sh_lang/sh_html.min.js +1 -0
  68. data/public/js/sh_lang/sh_java.min.js +1 -0
  69. data/public/js/sh_lang/sh_javascript.min.js +1 -0
  70. data/public/js/sh_lang/sh_javascript_dom.min.js +1 -0
  71. data/public/js/sh_lang/sh_latex.min.js +1 -0
  72. data/public/js/sh_lang/sh_ldap.min.js +1 -0
  73. data/public/js/sh_lang/sh_log.min.js +1 -0
  74. data/public/js/sh_lang/sh_lsm.min.js +1 -0
  75. data/public/js/sh_lang/sh_m4.min.js +1 -0
  76. data/public/js/sh_lang/sh_makefile.min.js +1 -0
  77. data/public/js/sh_lang/sh_oracle.min.js +1 -0
  78. data/public/js/sh_lang/sh_pascal.min.js +1 -0
  79. data/public/js/sh_lang/sh_perl.min.js +1 -0
  80. data/public/js/sh_lang/sh_php.min.js +1 -0
  81. data/public/js/sh_lang/sh_prolog.min.js +1 -0
  82. data/public/js/sh_lang/sh_properties.min.js +1 -0
  83. data/public/js/sh_lang/sh_python.min.js +1 -0
  84. data/public/js/sh_lang/sh_ruby.min.js +1 -0
  85. data/public/js/sh_lang/sh_scala.min.js +1 -0
  86. data/public/js/sh_lang/sh_sh.min.js +1 -0
  87. data/public/js/sh_lang/sh_slang.min.js +1 -0
  88. data/public/js/sh_lang/sh_sml.min.js +1 -0
  89. data/public/js/sh_lang/sh_spec.min.js +1 -0
  90. data/public/js/sh_lang/sh_sql.min.js +1 -0
  91. data/public/js/sh_lang/sh_tcl.min.js +1 -0
  92. data/public/js/sh_lang/sh_xml.min.js +1 -0
  93. data/public/js/sh_lang/sh_xorg.min.js +1 -0
  94. data/public/js/sh_main.min.js +4 -0
  95. data/public/js/showoff.js +629 -0
  96. data/public/js/showoffcore.js +13 -0
  97. data/views/index.erb +81 -0
  98. data/views/onepage.erb +35 -0
  99. metadata +217 -0
@@ -0,0 +1,361 @@
1
+ class ShowOffUtils
2
+ SHOWOFF_JSON_FILE = 'showoff.json'
3
+
4
+ def self.create(dirname,create_samples,dir='one')
5
+ Dir.mkdir(dirname) if !File.exists?(dirname)
6
+ Dir.chdir(dirname) do
7
+ if create_samples
8
+ # create section
9
+ Dir.mkdir(dir)
10
+
11
+ # create markdown file
12
+ File.open("#{dir}/01_slide.md", 'w+') do |f|
13
+ f.puts make_slide("My Presentation")
14
+ f.puts make_slide("Bullet Points","bullets incremental",["first point","second point","third point"])
15
+ end
16
+ end
17
+
18
+ # create showoff.json
19
+ File.open(SHOWOFF_JSON_FILE, 'w+') do |f|
20
+ f.puts "{ \"name\": \"My Preso\", \"sections\": [ {\"section\":\"#{dir}\"} ]}"
21
+ end
22
+
23
+ if create_samples
24
+ puts "done. run 'showoff serve' in #{dirname}/ dir to see slideshow"
25
+ else
26
+ puts "done. add slides, modify #{SHOWOFF_JSON_FILE} and then run 'showoff serve' in #{dirname}/ dir to see slideshow"
27
+ end
28
+ end
29
+ end
30
+
31
+ HEROKU_GEMS_FILE = '.gems'
32
+ HEROKU_BUNDLER_GEMS_FILE = 'Gemfile'
33
+ HEROKU_CONFIG_FILE = 'config.ru'
34
+
35
+ # Setup presentation to run on Heroku
36
+ #
37
+ # name - String containing heroku name
38
+ # force - boolean if .gems/Gemfile and config.ru should be overwritten if they don't exist
39
+ # password - String containing password to protect your heroku site; nil means no password protection
40
+ # use_dot_gems - boolea that, if true, indicates we should use the old, deprecated .gems file instead of Bundler
41
+ def self.heroku(name,force,password,use_dot_gems)
42
+ if !File.exists?(SHOWOFF_JSON_FILE)
43
+ puts "fail. not a showoff directory"
44
+ return false
45
+ end
46
+
47
+ modified_something = false
48
+
49
+ if use_dot_gems
50
+ modified_something = create_gems_file(HEROKU_GEMS_FILE,
51
+ !password.nil?,
52
+ force,
53
+ lambda{ |gem| gem })
54
+ else
55
+ modified_something = create_gems_file(HEROKU_BUNDLER_GEMS_FILE,
56
+ !password.nil?,
57
+ force,
58
+ lambda{ |gem| "gem '#{gem}'" },
59
+ lambda{ "source :rubygems" })
60
+ end
61
+
62
+ create_file_if_needed(HEROKU_CONFIG_FILE,force) do |file|
63
+ modified_something = true
64
+ file.puts 'require "showoff"'
65
+ if password.nil?
66
+ file.puts 'run ShowOff.new'
67
+ else
68
+ file.puts 'require "rack"'
69
+ file.puts 'showoff_app = ShowOff.new'
70
+ file.puts 'protected_showoff = Rack::Auth::Basic.new(showoff_app) do |username, password|'
71
+ file.puts "\tpassword == '#{password}'"
72
+ file.puts 'end'
73
+ file.puts 'run protected_showoff'
74
+ end
75
+ end
76
+
77
+ if modified_something
78
+ puts "herokuized. run something like this to launch your heroku presentation:
79
+
80
+ heroku create #{name}"
81
+
82
+ if use_dot_gems
83
+ puts " git add #{HEROKU_GEMS_FILE} #{HEROKU_CONFIG_FILE}"
84
+ else
85
+ puts " bundle install
86
+ git add Gemfile.lock #{HEROKU_GEMS_FILE} #{HEROKU_CONFIG_FILE}"
87
+ end
88
+ puts " git commit -m 'herokuized'
89
+ git push heroku master
90
+ "
91
+ end
92
+ end
93
+
94
+ # generate a static version of the site into the gh-pages branch
95
+ def self.github
96
+ puts "Generating static content"
97
+ ShowOff.do_static(nil)
98
+ `git add static`
99
+ sha = `git write-tree`.chomp
100
+ tree_sha = `git rev-parse #{sha}:static`.chomp
101
+ `git read-tree HEAD` # reset staging to last-commit
102
+ ghp_sha = `git rev-parse gh-pages 2>/dev/null`.chomp
103
+ extra = ghp_sha != 'gh-pages' ? "-p #{ghp_sha}" : ''
104
+ commit_sha = `echo 'static presentation' | git commit-tree #{tree_sha} #{extra}`.chomp
105
+ `git update-ref refs/heads/gh-pages #{commit_sha}`
106
+ puts "I've updated your 'gh-pages' branch with the static version of your presentation."
107
+ puts "Push it to GitHub to publish it. Probably something like:"
108
+ puts
109
+ puts " git push origin gh-pages"
110
+ puts
111
+ end
112
+
113
+ # Makes a slide as a string.
114
+ # [title] title of the slide
115
+ # [classes] any "classes" to include, such as 'smaller', 'transition', etc.
116
+ # [content] slide content. Currently, if this is an array, it will make a bullet list. Otherwise
117
+ # the string value of this will be put in the slide as-is
118
+ def self.make_slide(title,classes="",content=nil)
119
+ slide = "!SLIDE #{classes}\n"
120
+ slide << "# #{title} #\n"
121
+ slide << "\n"
122
+ if content
123
+ if content.kind_of? Array
124
+ content.each { |x| slide << "* #{x.to_s}\n" }
125
+ else
126
+ slide << content.to_s
127
+ end
128
+ end
129
+ slide
130
+ end
131
+
132
+ TYPES = {
133
+ :default => lambda { |t,size,source,type| make_slide(t,"#{size} #{type}",source) },
134
+ 'title' => lambda { |t,size,dontcare| make_slide(t,size) },
135
+ 'bullets' => lambda { |t,size,dontcare| make_slide(t,"#{size} bullets incremental",["bullets","go","here"])},
136
+ 'smbullets' => lambda { |t,size,dontcare| make_slide(t,"#{size} smbullets incremental",["bullets","go","here","and","here"])},
137
+ 'code' => lambda { |t,size,src| make_slide(t,size,blank?(src) ? " @@@ Ruby\n code_here()" : src) },
138
+ 'commandline' => lambda { |t,size,dontcare| make_slide(t,"#{size} commandline"," $ command here\n output here")},
139
+ 'full-page' => lambda { |t,size,dontcare| make_slide(t,"#{size} full-page","![Image Description](image/ref.png)")},
140
+ }
141
+
142
+
143
+ # Adds a new slide to a given dir, giving it a number such that it falls after all slides
144
+ # in that dir.
145
+ # Options are:
146
+ # [:dir] - dir where we put the slide (if omitted, slide is output to $stdout)
147
+ # [:name] - name of the file, without the number prefix. (if omitted, a default is used)
148
+ # [:title] - title in the slide. If not specified the source file name is
149
+ # used. If THAT is not specified, uses the value of +:name+. If THAT is not
150
+ # specified, a suitable default is used
151
+ # [:code] - path to a source file to use as content (force :type to be 'code')
152
+ # [:number] - true if numbering should be done, false if not
153
+ # [:type] - the type of slide to create
154
+ def self.add_slide(options)
155
+
156
+ add_new_dir(options[:dir]) if options[:dir] && !File.exists?(options[:dir])
157
+
158
+ options[:type] = 'code' if options[:code]
159
+
160
+ title = determine_title(options[:title],options[:name],options[:code])
161
+
162
+ options[:name] = 'new_slide' if !options[:name]
163
+
164
+ size,source = determine_size_and_source(options[:code])
165
+ type = options[:type] || :default
166
+ slide = TYPES[type].call(title,size,source)
167
+
168
+ if options[:dir]
169
+ filename = determine_filename(options[:dir],options[:name],options[:number])
170
+ write_file(filename,slide)
171
+ else
172
+ puts slide
173
+ puts
174
+ end
175
+
176
+ end
177
+
178
+ # Adds the given directory to this presentation, appending it to
179
+ # the end of showoff.json as well
180
+ def self.add_new_dir(dir)
181
+ puts "Creating #{dir}..."
182
+ Dir.mkdir dir
183
+
184
+ showoff_json = JSON.parse(File.read(SHOWOFF_JSON_FILE))
185
+ showoff_json["section"] = dir
186
+ File.open(SHOWOFF_JSON_FILE,'w') do |file|
187
+ file.puts JSON.generate(showoff_json)
188
+ end
189
+ puts "#{SHOWOFF_JSON_FILE} updated"
190
+ end
191
+
192
+ def self.blank?(string)
193
+ string.nil? || string.strip.length == 0
194
+ end
195
+
196
+ def self.determine_size_and_source(code)
197
+ size = ""
198
+ source = ""
199
+ if code
200
+ source,lines,width = read_code(code)
201
+ size = adjust_size(lines,width)
202
+ end
203
+ [size,source]
204
+ end
205
+
206
+ def self.write_file(filename,slide)
207
+ File.open(filename,'w') do |file|
208
+ file.puts slide
209
+ end
210
+ puts "Wrote #{filename}"
211
+ end
212
+
213
+ def self.determine_filename(slide_dir,slide_name,number)
214
+ filename = "#{slide_dir}/#{slide_name}.md"
215
+ if number
216
+ max = find_next_number(slide_dir)
217
+ filename = "#{slide_dir}/#{max}_#{slide_name}.md"
218
+ end
219
+ filename
220
+ end
221
+
222
+ # Finds the next number in the given dir to
223
+ # name a slide as the last slide in the dir.
224
+ def self.find_next_number(slide_dir)
225
+ max = 0
226
+ Dir.open(slide_dir).each do |file|
227
+ if file =~ /(\d+).*\.md/
228
+ num = $1.to_i
229
+ max = num if num > max
230
+ end
231
+ end
232
+ max += 1
233
+ max = "0#{max}" if max < 10
234
+ max
235
+ end
236
+
237
+ def self.determine_title(title,slide_name,code)
238
+ if blank?(title)
239
+ title = slide_name
240
+ title = File.basename(code) if code
241
+ end
242
+ title = "Title here" if blank?(title)
243
+ title
244
+ end
245
+
246
+ # Determines a more optimal value for the size (e.g. small vs. smaller)
247
+ # based upon the size of the code being formatted.
248
+ def self.adjust_size(lines,width)
249
+ size = ""
250
+ # These values determined empircally
251
+ size = "small" if width > 50
252
+ size = "small" if lines > 15
253
+ size = "smaller" if width > 57
254
+ size = "smaller" if lines > 19
255
+ puts "warning, some lines are too long and the code may be cut off" if width > 65
256
+ puts "warning, your code is too long and the code may be cut off" if lines > 23
257
+ size
258
+ end
259
+
260
+ # Reads the code from the source file, returning
261
+ # the code, indented for markdown, as well as the number of lines
262
+ # and the width of the largest line
263
+ def self.read_code(source_file)
264
+ code = " @@@ #{lang(source_file)}\n"
265
+ lines = 0
266
+ width = 0
267
+ File.open(source_file) do |code_file|
268
+ code_file.readlines.each do |line|
269
+ code += " #{line}"
270
+ lines += 1
271
+ width = line.length if line.length > width
272
+ end
273
+ end
274
+ [code,lines,width]
275
+ end
276
+
277
+ def self.showoff_sections(dir = '.')
278
+ index = File.join(dir, ShowOffUtils::SHOWOFF_JSON_FILE )
279
+ order = nil
280
+ if File.exists?(index)
281
+ data = JSON.parse(File.read(index))
282
+ pp data
283
+ if data.is_a?(Hash)
284
+ order = data['sections']
285
+ else
286
+ order = data
287
+ end
288
+ order = order.map { |s| s['section'] }
289
+ end
290
+ order
291
+ end
292
+
293
+ def self.showoff_title(dir = '.')
294
+ index = File.join(dir, ShowOffUtils::SHOWOFF_JSON_FILE )
295
+ order = nil
296
+ if File.exists?(index)
297
+ data = JSON.parse(File.read(index))
298
+ data.is_a?(Hash) && data['name'] || "Presentation"
299
+ end
300
+ end
301
+
302
+ EXTENSIONS = {
303
+ 'pl' => 'perl',
304
+ 'rb' => 'ruby',
305
+ 'erl' => 'erlang',
306
+ # so not exhaustive, but probably good enough for now
307
+ }
308
+
309
+ def self.lang(source_file)
310
+ ext = File.extname(source_file).gsub(/^\./,'')
311
+ EXTENSIONS[ext] || ext
312
+ end
313
+
314
+ REQUIRED_GEMS = %w(bluecloth nokogiri showoff gli)
315
+
316
+ # Creates the file that lists the gems for heroku
317
+ #
318
+ # filename - String name of the file
319
+ # password - Boolean to indicate if we are setting a password
320
+ # force - Boolean to indicate if we should overwrite the existing file
321
+ # formatter - Proc/lambda that takes 1 argument, the gem name, and formats it for the file
322
+ # This is so we can support both the old .gems and the new bundler Gemfile
323
+ # header - Proc/lambda that creates any header information in the file
324
+ #
325
+ # Returns a boolean indicating that we had to create the file or not.
326
+ def self.create_gems_file(filename,password,force,formatter,header=nil)
327
+ create_file_if_needed(filename,force) do |file|
328
+ file.puts header.call unless header.nil?
329
+ REQUIRED_GEMS.each { |gem| file.puts formatter.call(gem) }
330
+ file.puts formatter.call("rack") if password
331
+ end
332
+ end
333
+
334
+ # Creates the given filename if it doesn't exist or if force is true
335
+ #
336
+ # filename - String name of the file to create
337
+ # force - if true, the file will always be created, if false, only create
338
+ # if it's not there
339
+ # block - takes a block that will be given the file handle to write
340
+ # data into the file IF it's being created
341
+ #
342
+ # Examples
343
+ #
344
+ # create_file_if_needed("config.ru",false) do |file|
345
+ # file.puts "require 'showoff'"
346
+ # file.puts "run ShowOff.new"
347
+ # end
348
+ #
349
+ # Returns true if the file was created
350
+ def self.create_file_if_needed(filename,force)
351
+ if !File.exists?(filename) || force
352
+ File.open(filename, 'w+') do |f|
353
+ yield f
354
+ end
355
+ true
356
+ else
357
+ puts "#{filename} exists; not overwriting (see showoff help heroku)"
358
+ false
359
+ end
360
+ end
361
+ end
@@ -0,0 +1,114 @@
1
+ /* Styles for jQuery menu widget
2
+ Author: Maggie Wachs, maggie@filamentgroup.com
3
+ Date: September 2008
4
+ */
5
+
6
+
7
+ /* REQUIRED STYLES - the menus will only render correctly with these rules */
8
+
9
+ .fg-menu-container { position: absolute; top:0; left:-999px; padding: .4em; overflow: hidden; }
10
+ .fg-menu-container.fg-menu-flyout { overflow: visible; }
11
+
12
+ .fg-menu, .fg-menu ul { list-style-type:none; padding: 0; margin:0; }
13
+
14
+ .fg-menu { position:relative; }
15
+ .fg-menu-flyout .fg-menu { position:static; }
16
+
17
+ .fg-menu ul { position:absolute; top:0; }
18
+ .fg-menu ul ul { top:-1px; }
19
+
20
+ .fg-menu-container.fg-menu-ipod .fg-menu-content,
21
+ .fg-menu-container.fg-menu-ipod .fg-menu-content ul { background: none !important; }
22
+
23
+ .fg-menu.fg-menu-scroll,
24
+ .fg-menu ul.fg-menu-scroll { overflow: scroll; overflow-x: hidden; }
25
+
26
+ .fg-menu li { clear:both; float:left; width:100%; margin: 0; padding:0; border: 0; }
27
+ .fg-menu li li { font-size:1em; } /* inner li font size must be reset so that they don't blow up */
28
+
29
+ .fg-menu-flyout ul ul { padding: .4em; }
30
+ .fg-menu-flyout li { position:relative; }
31
+
32
+ .fg-menu-scroll { overflow: scroll; overflow-x: hidden; }
33
+
34
+ .fg-menu-breadcrumb { margin: 0; padding: 0; }
35
+
36
+ .fg-menu-footer { margin-top: .4em; padding: .4em; }
37
+ .fg-menu-header { margin-bottom: .4em; padding: .4em; }
38
+
39
+ .fg-menu-breadcrumb li { float: left; list-style: none; margin: 0; padding: 0 .2em; font-size: .9em; opacity: .7; }
40
+ .fg-menu-breadcrumb li.fg-menu-prev-list,
41
+ .fg-menu-breadcrumb li.fg-menu-current-crumb { clear: left; float: none; opacity: 1; }
42
+ .fg-menu-breadcrumb li.fg-menu-current-crumb { padding-top: .2em; }
43
+
44
+ .fg-menu-breadcrumb a,
45
+ .fg-menu-breadcrumb span { float: left; }
46
+
47
+ .fg-menu-footer a:link,
48
+ .fg-menu-footer a:visited { float:left; width:100%; text-decoration: none; }
49
+ .fg-menu-footer a:hover,
50
+ .fg-menu-footer a:active { }
51
+
52
+ .fg-menu-footer a span { float:left; cursor: pointer; }
53
+
54
+ .fg-menu-breadcrumb .fg-menu-prev-list a:link,
55
+ .fg-menu-breadcrumb .fg-menu-prev-list a:visited,
56
+ .fg-menu-breadcrumb .fg-menu-prev-list a:hover,
57
+ .fg-menu-breadcrumb .fg-menu-prev-list a:active { background-image: none; text-decoration:none; }
58
+
59
+ .fg-menu-breadcrumb .fg-menu-prev-list a { float: left; padding-right: .4em; }
60
+ .fg-menu-breadcrumb .fg-menu-prev-list a .ui-icon { float: left; }
61
+
62
+ .fg-menu-breadcrumb .fg-menu-current-crumb a:link,
63
+ .fg-menu-breadcrumb .fg-menu-current-crumb a:visited,
64
+ .fg-menu-breadcrumb .fg-menu-current-crumb a:hover,
65
+ .fg-menu-breadcrumb .fg-menu-current-crumb a:active { display:block; background-image:none; font-size:1.3em; text-decoration:none; }
66
+
67
+
68
+
69
+ /* REQUIRED LINK STYLES: links are "display:block" by default; if the menu options are split into
70
+ selectable node links and 'next' links, the script floats the node links left and floats the 'next' links to the right */
71
+
72
+ .fg-menu a:link,
73
+ .fg-menu a:visited,
74
+ .fg-menu a:hover,
75
+ .fg-menu a:active { float:left; width:92%; padding:.3em 3%; text-decoration:none; outline: 0 !important; }
76
+
77
+ .fg-menu a { border: 1px dashed transparent; }
78
+
79
+ .fg-menu a.ui-state-default:link,
80
+ .fg-menu a.ui-state-default:visited,
81
+ .fg-menu a.ui-state-default:hover,
82
+ .fg-menu a.ui-state-default:active,
83
+ .fg-menu a.ui-state-hover:link,
84
+ .fg-menu a.ui-state-hover:visited,
85
+ .fg-menu a.ui-state-hover:hover,
86
+ .fg-menu a.ui-state-hover:active,
87
+ .fg-menu a.ui-state-active:link,
88
+ .fg-menu a.ui-state-active:visited,
89
+ .fg-menu a.ui-state-active:hover,
90
+ .fg-menu a.ui-state-active:active { border-style: solid; font-weight: normal; }
91
+
92
+ .fg-menu a span { display:block; cursor:pointer; }
93
+
94
+
95
+ /* SUGGESTED STYLES - for use with jQuery UI Themeroller CSS */
96
+
97
+ .fg-menu-indicator span { float:left; }
98
+ .fg-menu-indicator span.ui-icon { float:right; }
99
+
100
+ .fg-menu-content.ui-widget-content,
101
+ .fg-menu-content ul.ui-widget-content { border:0; }
102
+
103
+
104
+ /* ICONS AND DIVIDERS */
105
+
106
+ .fg-menu.fg-menu-has-icons a:link,
107
+ .fg-menu.fg-menu-has-icons a:visited,
108
+ .fg-menu.fg-menu-has-icons a:hover,
109
+ .fg-menu.fg-menu-has-icons a:active { padding-left:20px; }
110
+
111
+ .fg-menu .horizontal-divider hr, .fg-menu .horizontal-divider span { padding:0; margin:5px .6em; }
112
+ .fg-menu .horizontal-divider hr { border:0; height:1px; }
113
+ .fg-menu .horizontal-divider span { font-size:.9em; text-transform: uppercase; padding-left:.2em; }
114
+