polyphony 0.38 → 0.43

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.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +11 -2
  3. data/.gitignore +2 -2
  4. data/.rubocop.yml +30 -0
  5. data/CHANGELOG.md +25 -2
  6. data/Gemfile.lock +15 -12
  7. data/README.md +2 -1
  8. data/Rakefile +3 -3
  9. data/TODO.md +27 -97
  10. data/docs/_config.yml +56 -7
  11. data/docs/_sass/custom/custom.scss +0 -30
  12. data/docs/_sass/overrides.scss +0 -46
  13. data/docs/{user-guide → _user-guide}/all-about-timers.md +0 -0
  14. data/docs/_user-guide/index.md +9 -0
  15. data/docs/{user-guide → _user-guide}/web-server.md +0 -0
  16. data/docs/api-reference/fiber.md +2 -2
  17. data/docs/api-reference/index.md +9 -0
  18. data/docs/api-reference/polyphony-process.md +1 -1
  19. data/docs/api-reference/thread.md +1 -1
  20. data/docs/faq.md +21 -11
  21. data/docs/getting-started/index.md +10 -0
  22. data/docs/getting-started/installing.md +2 -6
  23. data/docs/getting-started/overview.md +486 -0
  24. data/docs/getting-started/tutorial.md +27 -19
  25. data/docs/index.md +1 -1
  26. data/docs/main-concepts/concurrency.md +0 -5
  27. data/docs/main-concepts/design-principles.md +69 -21
  28. data/docs/main-concepts/extending.md +1 -1
  29. data/docs/main-concepts/index.md +9 -0
  30. data/examples/core/01-spinning-up-fibers.rb +1 -0
  31. data/examples/core/03-interrupting.rb +4 -1
  32. data/examples/core/04-handling-signals.rb +19 -0
  33. data/examples/core/xx-agent.rb +102 -0
  34. data/examples/core/xx-sleeping.rb +14 -6
  35. data/examples/io/tunnel.rb +48 -0
  36. data/examples/io/xx-irb.rb +1 -1
  37. data/examples/performance/thread-vs-fiber/polyphony_mt_server.rb +7 -6
  38. data/examples/performance/thread-vs-fiber/polyphony_server.rb +13 -36
  39. data/examples/performance/thread-vs-fiber/polyphony_server_read_loop.rb +58 -0
  40. data/examples/performance/xx-array.rb +11 -0
  41. data/examples/performance/xx-fiber-switch.rb +9 -0
  42. data/examples/performance/xx-snooze.rb +15 -0
  43. data/ext/{gyro → polyphony}/extconf.rb +2 -2
  44. data/ext/{gyro → polyphony}/fiber.c +17 -23
  45. data/ext/{gyro → polyphony}/libev.c +0 -0
  46. data/ext/{gyro → polyphony}/libev.h +0 -0
  47. data/ext/polyphony/libev_agent.c +718 -0
  48. data/ext/polyphony/libev_queue.c +216 -0
  49. data/ext/{gyro/gyro.c → polyphony/polyphony.c} +16 -40
  50. data/ext/{gyro/gyro.h → polyphony/polyphony.h} +19 -39
  51. data/ext/polyphony/polyphony_ext.c +23 -0
  52. data/ext/{gyro → polyphony}/socket.c +21 -18
  53. data/ext/polyphony/thread.c +206 -0
  54. data/ext/{gyro → polyphony}/tracing.c +1 -1
  55. data/lib/polyphony.rb +19 -14
  56. data/lib/polyphony/adapters/irb.rb +1 -1
  57. data/lib/polyphony/adapters/postgres.rb +6 -5
  58. data/lib/polyphony/adapters/process.rb +5 -5
  59. data/lib/polyphony/adapters/trace.rb +28 -28
  60. data/lib/polyphony/core/channel.rb +3 -3
  61. data/lib/polyphony/core/exceptions.rb +1 -1
  62. data/lib/polyphony/core/global_api.rb +13 -11
  63. data/lib/polyphony/core/resource_pool.rb +3 -3
  64. data/lib/polyphony/core/sync.rb +2 -2
  65. data/lib/polyphony/core/thread_pool.rb +6 -6
  66. data/lib/polyphony/core/throttler.rb +13 -6
  67. data/lib/polyphony/event.rb +27 -0
  68. data/lib/polyphony/extensions/core.rb +22 -14
  69. data/lib/polyphony/extensions/fiber.rb +4 -4
  70. data/lib/polyphony/extensions/io.rb +59 -25
  71. data/lib/polyphony/extensions/openssl.rb +36 -16
  72. data/lib/polyphony/extensions/socket.rb +27 -9
  73. data/lib/polyphony/extensions/thread.rb +16 -9
  74. data/lib/polyphony/net.rb +9 -9
  75. data/lib/polyphony/version.rb +1 -1
  76. data/polyphony.gemspec +4 -4
  77. data/test/helper.rb +14 -1
  78. data/test/test_agent.rb +124 -0
  79. data/test/{test_async.rb → test_event.rb} +15 -7
  80. data/test/test_ext.rb +25 -4
  81. data/test/test_fiber.rb +19 -10
  82. data/test/test_global_api.rb +4 -4
  83. data/test/test_io.rb +46 -24
  84. data/test/test_queue.rb +74 -0
  85. data/test/test_signal.rb +3 -40
  86. data/test/test_socket.rb +34 -0
  87. data/test/test_thread.rb +37 -16
  88. data/test/test_trace.rb +6 -5
  89. metadata +40 -43
  90. data/docs/_includes/nav.html +0 -51
  91. data/docs/_includes/prevnext.html +0 -17
  92. data/docs/_layouts/default.html +0 -106
  93. data/docs/api-reference.md +0 -11
  94. data/docs/api-reference/gyro-async.md +0 -57
  95. data/docs/api-reference/gyro-child.md +0 -29
  96. data/docs/api-reference/gyro-queue.md +0 -44
  97. data/docs/api-reference/gyro-timer.md +0 -51
  98. data/docs/api-reference/gyro.md +0 -25
  99. data/docs/getting-started.md +0 -10
  100. data/docs/main-concepts.md +0 -10
  101. data/docs/user-guide.md +0 -10
  102. data/examples/core/forever_sleep.rb +0 -19
  103. data/ext/gyro/async.c +0 -162
  104. data/ext/gyro/child.c +0 -141
  105. data/ext/gyro/gyro_ext.c +0 -33
  106. data/ext/gyro/io.c +0 -489
  107. data/ext/gyro/queue.c +0 -142
  108. data/ext/gyro/selector.c +0 -228
  109. data/ext/gyro/signal.c +0 -133
  110. data/ext/gyro/thread.c +0 -308
  111. data/ext/gyro/timer.c +0 -149
  112. data/test/test_timer.rb +0 -56
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helper'
4
+
5
+ class SocketTest < MiniTest::Test
6
+ def setup
7
+ super
8
+ end
9
+
10
+ def test_tcp
11
+ port = rand(1234..5678)
12
+ server = TCPServer.new('127.0.0.1', port)
13
+
14
+ server_fiber = spin do
15
+ while (socket = server.accept)
16
+ spin do
17
+ while (data = socket.gets(8192))
18
+ socket << data
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ snooze
25
+ client = TCPSocket.new('127.0.0.1', port)
26
+ client.write("1234\n")
27
+ assert_equal "1234\n", client.readpartial(8192)
28
+ client.close
29
+ ensure
30
+ server_fiber&.stop
31
+ server_fiber&.await
32
+ server&.close
33
+ end
34
+ end
@@ -8,14 +8,20 @@ class ThreadTest < MiniTest::Test
8
8
  buffer = []
9
9
  f = spin { (1..3).each { |i| snooze; buffer << i } }
10
10
  t = Thread.new do
11
+ sleep 0.01
11
12
  s1 = spin { (11..13).each { |i| snooze; buffer << i } }
12
13
  s2 = spin { (21..23).each { |i| snooze; buffer << i } }
14
+ sleep 0.02
13
15
  Fiber.current.await_all_children
14
16
  end
15
17
  f.join
16
18
  t.join
19
+ t = nil
17
20
 
18
21
  assert_equal [1, 2, 3, 11, 12, 13, 21, 22, 23], buffer.sort
22
+ ensure
23
+ t&.kill
24
+ t&.join
19
25
  end
20
26
 
21
27
  def test_thread_join
@@ -24,11 +30,13 @@ class ThreadTest < MiniTest::Test
24
30
  t = Thread.new { sleep 0.01; buffer << 4; :foo }
25
31
 
26
32
  r = t.join
33
+ t = nil
27
34
 
28
- assert_equal [1, 2, 3, 4], buffer
29
35
  assert_equal :foo, r
36
+ assert_equal [1, 2, 3, 4], buffer
30
37
  ensure
31
- t.kill
38
+ t&.kill
39
+ t&.join
32
40
  end
33
41
 
34
42
  def test_thread_join_with_timeout
@@ -37,6 +45,7 @@ class ThreadTest < MiniTest::Test
37
45
  t = Thread.new { sleep 1; buffer << 4 }
38
46
  t0 = Time.now
39
47
  r = t.join(0.01)
48
+ t = nil
40
49
 
41
50
  assert Time.now - t0 < 0.2
42
51
  assert_equal [1, 2, 3], buffer
@@ -44,7 +53,8 @@ class ThreadTest < MiniTest::Test
44
53
  ensure
45
54
  # killing the thread will prevent stopping the sleep timer, as well as the
46
55
  # thread's event selector, leading to a memory leak.
47
- t&.kill if t&.alive?
56
+ t&.kill
57
+ t&.join
48
58
  end
49
59
 
50
60
  def test_thread_await_alias_method
@@ -52,11 +62,13 @@ class ThreadTest < MiniTest::Test
52
62
  spin { (1..3).each { |i| snooze; buffer << i } }
53
63
  t = Thread.new { sleep 0.01; buffer << 4; :foo }
54
64
  r = t.await
65
+ t = nil
55
66
 
56
67
  assert_equal [1, 2, 3, 4], buffer
57
68
  assert_equal :foo, r
58
69
  ensure
59
- t.kill
70
+ t&.kill
71
+ t&.join
60
72
  end
61
73
 
62
74
  def test_join_race_condition_on_thread_spawning
@@ -65,27 +77,33 @@ class ThreadTest < MiniTest::Test
65
77
  :foo
66
78
  end
67
79
  r = t.join
80
+ t = nil
68
81
  assert_equal :foo, r
82
+ ensure
83
+ t&.kill
84
+ t&.join
69
85
  end
70
86
 
71
87
  def test_thread_uncaught_exception_propagation
72
- t = Thread.new do
73
- sleep 1
74
- end
75
- snooze
76
- t.kill
77
- t.await
88
+ ready = Polyphony::Event.new
78
89
 
79
90
  t = Thread.new do
91
+ ready.signal
92
+ sleep 0.01
80
93
  raise 'foo'
81
94
  end
82
95
  e = nil
83
96
  begin
84
- t.await
97
+ ready.await
98
+ r = t.await
85
99
  rescue Exception => e
86
100
  end
101
+ t = nil
87
102
  assert_kind_of RuntimeError, e
88
103
  assert_equal 'foo', e.message
104
+ ensure
105
+ t&.kill
106
+ t&.join
89
107
  end
90
108
 
91
109
  def test_thread_inspect
@@ -102,9 +120,8 @@ class ThreadTest < MiniTest::Test
102
120
  p e
103
121
  puts e.backtrace.join("\n")
104
122
  ensure
105
- t.kill
106
- sleep 0.005
107
- t.join
123
+ t&.kill
124
+ t&.join
108
125
  end
109
126
 
110
127
  def test_that_suspend_returns_immediately_if_no_watchers
@@ -113,14 +130,14 @@ class ThreadTest < MiniTest::Test
113
130
  records << r if r[:event] =~ /^fiber_/
114
131
  end
115
132
  t.enable
116
- Gyro.trace(true)
133
+ Polyphony.trace(true)
117
134
 
118
135
  suspend
119
136
  t.disable
120
137
  assert_equal [:fiber_switchpoint], records.map { |r| r[:event] }
121
138
  ensure
122
139
  t&.disable
123
- Gyro.trace(false)
140
+ Polyphony.trace(false)
124
141
  end
125
142
 
126
143
  def test_thread_child_fiber_termination
@@ -143,7 +160,11 @@ class ThreadTest < MiniTest::Test
143
160
  assert_equal 2, t.main_fiber.children.size
144
161
  t.kill
145
162
  t.join
163
+ t = nil
146
164
 
147
165
  assert_equal [:foo, :bar], buffer
166
+ ensure
167
+ t&.kill
168
+ t&.join
148
169
  end
149
170
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'helper'
4
+ require 'polyphony/adapters/trace'
4
5
 
5
6
  class TraceTest < MiniTest::Test
6
7
  def test_tracing_disabled
@@ -11,13 +12,13 @@ class TraceTest < MiniTest::Test
11
12
  assert_equal 0, records.size
12
13
  ensure
13
14
  t&.disable
14
- Gyro.trace(nil)
15
+ Polyphony.trace(nil)
15
16
  end
16
17
 
17
18
  def test_tracing_enabled
18
19
  records = []
19
20
  t = Polyphony::Trace.new(:fiber_all) { |r| records << r if r[:event] =~ /^fiber_/ }
20
- Gyro.trace(true)
21
+ Polyphony.trace(true)
21
22
  t.enable
22
23
  snooze
23
24
  t.disable
@@ -28,14 +29,14 @@ class TraceTest < MiniTest::Test
28
29
  assert_equal [Fiber.current], records.map { |r| r[:fiber] }.uniq
29
30
  ensure
30
31
  t&.disable
31
- Gyro.trace(nil)
32
+ Polyphony.trace(nil)
32
33
  end
33
34
 
34
35
  def test_2_fiber_trace
35
36
  records = []
36
37
  t = Polyphony::Trace.new(:fiber_all) { |r| records << r if r[:event] =~ /^fiber_/ }
37
38
  t.enable
38
- Gyro.trace(true)
39
+ Polyphony.trace(true)
39
40
 
40
41
  f = spin { sleep 0 }
41
42
  suspend
@@ -61,6 +62,6 @@ class TraceTest < MiniTest::Test
61
62
  ], events
62
63
  ensure
63
64
  t&.disable
64
- Gyro.trace(nil)
65
+ Polyphony.trace(nil)
65
66
  end
66
67
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: polyphony
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.38'
4
+ version: '0.43'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-13 00:00:00.000000000 Z
11
+ date: 2020-07-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -86,28 +86,28 @@ dependencies:
86
86
  requirements:
87
87
  - - '='
88
88
  - !ruby/object:Gem::Version
89
- version: 0.80.0
89
+ version: 0.85.1
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - '='
95
95
  - !ruby/object:Gem::Version
96
- version: 0.80.0
96
+ version: 0.85.1
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: pg
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - '='
102
102
  - !ruby/object:Gem::Version
103
- version: 1.1.3
103
+ version: 1.1.4
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - '='
109
109
  - !ruby/object:Gem::Version
110
- version: 1.1.3
110
+ version: 1.1.4
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: rake-compiler
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -212,19 +212,19 @@ dependencies:
212
212
  requirements:
213
213
  - - "~>"
214
214
  - !ruby/object:Gem::Version
215
- version: 0.2.7
215
+ version: 0.3.0
216
216
  type: :development
217
217
  prerelease: false
218
218
  version_requirements: !ruby/object:Gem::Requirement
219
219
  requirements:
220
220
  - - "~>"
221
221
  - !ruby/object:Gem::Version
222
- version: 0.2.7
222
+ version: 0.3.0
223
223
  description:
224
224
  email: ciconia@gmail.com
225
225
  executables: []
226
226
  extensions:
227
- - ext/gyro/extconf.rb
227
+ - ext/polyphony/extconf.rb
228
228
  extra_rdoc_files:
229
229
  - README.md
230
230
  files:
@@ -242,19 +242,14 @@ files:
242
242
  - TODO.md
243
243
  - bin/polyphony-debug
244
244
  - docs/_config.yml
245
- - docs/_includes/nav.html
246
- - docs/_includes/prevnext.html
247
- - docs/_layouts/default.html
248
245
  - docs/_sass/custom/custom.scss
249
246
  - docs/_sass/overrides.scss
250
- - docs/api-reference.md
247
+ - docs/_user-guide/all-about-timers.md
248
+ - docs/_user-guide/index.md
249
+ - docs/_user-guide/web-server.md
251
250
  - docs/api-reference/exception.md
252
251
  - docs/api-reference/fiber.md
253
- - docs/api-reference/gyro-async.md
254
- - docs/api-reference/gyro-child.md
255
- - docs/api-reference/gyro-queue.md
256
- - docs/api-reference/gyro-timer.md
257
- - docs/api-reference/gyro.md
252
+ - docs/api-reference/index.md
258
253
  - docs/api-reference/io.md
259
254
  - docs/api-reference/object.md
260
255
  - docs/api-reference/polyphony-baseexception.md
@@ -272,19 +267,17 @@ files:
272
267
  - docs/assets/img/echo-fibers.svg
273
268
  - docs/assets/img/sleeping-fiber.svg
274
269
  - docs/faq.md
275
- - docs/getting-started.md
270
+ - docs/getting-started/index.md
276
271
  - docs/getting-started/installing.md
272
+ - docs/getting-started/overview.md
277
273
  - docs/getting-started/tutorial.md
278
274
  - docs/index.md
279
- - docs/main-concepts.md
280
275
  - docs/main-concepts/concurrency.md
281
276
  - docs/main-concepts/design-principles.md
282
277
  - docs/main-concepts/exception-handling.md
283
278
  - docs/main-concepts/extending.md
284
279
  - docs/main-concepts/fiber-scheduling.md
285
- - docs/user-guide.md
286
- - docs/user-guide/all-about-timers.md
287
- - docs/user-guide/web-server.md
280
+ - docs/main-concepts/index.md
288
281
  - examples/adapters/pg_client.rb
289
282
  - examples/adapters/pg_notify.rb
290
283
  - examples/adapters/pg_pool.rb
@@ -296,7 +289,8 @@ files:
296
289
  - examples/core/01-spinning-up-fibers.rb
297
290
  - examples/core/02-awaiting-fibers.rb
298
291
  - examples/core/03-interrupting.rb
299
- - examples/core/forever_sleep.rb
292
+ - examples/core/04-handling-signals.rb
293
+ - examples/core/xx-agent.rb
300
294
  - examples/core/xx-at_exit.rb
301
295
  - examples/core/xx-caller.rb
302
296
  - examples/core/xx-channels.rb
@@ -335,6 +329,7 @@ files:
335
329
  - examples/core/xx-trace.rb
336
330
  - examples/core/xx-using-a-mutex.rb
337
331
  - examples/core/xx-worker-thread.rb
332
+ - examples/io/tunnel.rb
338
333
  - examples/io/xx-backticks.rb
339
334
  - examples/io/xx-echo_client.rb
340
335
  - examples/io/xx-echo_client_from_stdin.rb
@@ -358,27 +353,14 @@ files:
358
353
  - examples/performance/snooze_raw.rb
359
354
  - examples/performance/thread-vs-fiber/polyphony_mt_server.rb
360
355
  - examples/performance/thread-vs-fiber/polyphony_server.rb
356
+ - examples/performance/thread-vs-fiber/polyphony_server_read_loop.rb
361
357
  - examples/performance/thread-vs-fiber/threaded_server.rb
362
358
  - examples/performance/thread-vs-fiber/xx-httparty_multi.rb
363
359
  - examples/performance/thread-vs-fiber/xx-httparty_threaded.rb
364
360
  - examples/performance/thread_pool_perf.rb
365
- - ext/gyro/async.c
366
- - ext/gyro/child.c
367
- - ext/gyro/extconf.rb
368
- - ext/gyro/fiber.c
369
- - ext/gyro/gyro.c
370
- - ext/gyro/gyro.h
371
- - ext/gyro/gyro_ext.c
372
- - ext/gyro/io.c
373
- - ext/gyro/libev.c
374
- - ext/gyro/libev.h
375
- - ext/gyro/queue.c
376
- - ext/gyro/selector.c
377
- - ext/gyro/signal.c
378
- - ext/gyro/socket.c
379
- - ext/gyro/thread.c
380
- - ext/gyro/timer.c
381
- - ext/gyro/tracing.c
361
+ - examples/performance/xx-array.rb
362
+ - examples/performance/xx-fiber-switch.rb
363
+ - examples/performance/xx-snooze.rb
382
364
  - ext/libev/Changes
383
365
  - ext/libev/LICENSE
384
366
  - ext/libev/README
@@ -395,6 +377,18 @@ files:
395
377
  - ext/libev/ev_win32.c
396
378
  - ext/libev/ev_wrap.h
397
379
  - ext/libev/test_libev_win32.c
380
+ - ext/polyphony/extconf.rb
381
+ - ext/polyphony/fiber.c
382
+ - ext/polyphony/libev.c
383
+ - ext/polyphony/libev.h
384
+ - ext/polyphony/libev_agent.c
385
+ - ext/polyphony/libev_queue.c
386
+ - ext/polyphony/polyphony.c
387
+ - ext/polyphony/polyphony.h
388
+ - ext/polyphony/polyphony_ext.c
389
+ - ext/polyphony/socket.c
390
+ - ext/polyphony/thread.c
391
+ - ext/polyphony/tracing.c
398
392
  - lib/polyphony.rb
399
393
  - lib/polyphony/adapters/fs.rb
400
394
  - lib/polyphony/adapters/irb.rb
@@ -409,6 +403,7 @@ files:
409
403
  - lib/polyphony/core/sync.rb
410
404
  - lib/polyphony/core/thread_pool.rb
411
405
  - lib/polyphony/core/throttler.rb
406
+ - lib/polyphony/event.rb
412
407
  - lib/polyphony/extensions/core.rb
413
408
  - lib/polyphony/extensions/fiber.rb
414
409
  - lib/polyphony/extensions/io.rb
@@ -423,20 +418,22 @@ files:
423
418
  - test/helper.rb
424
419
  - test/run.rb
425
420
  - test/stress.rb
426
- - test/test_async.rb
421
+ - test/test_agent.rb
422
+ - test/test_event.rb
427
423
  - test/test_ext.rb
428
424
  - test/test_fiber.rb
429
425
  - test/test_global_api.rb
430
426
  - test/test_io.rb
431
427
  - test/test_kernel.rb
432
428
  - test/test_process_supervision.rb
429
+ - test/test_queue.rb
433
430
  - test/test_resource_pool.rb
434
431
  - test/test_signal.rb
432
+ - test/test_socket.rb
435
433
  - test/test_supervise.rb
436
434
  - test/test_thread.rb
437
435
  - test/test_thread_pool.rb
438
436
  - test/test_throttler.rb
439
- - test/test_timer.rb
440
437
  - test/test_trace.rb
441
438
  homepage: https://digital-fabric.github.io/polyphony
442
439
  licenses:
@@ -1,51 +0,0 @@
1
- <nav role="navigation" aria-label="Main navigation">
2
- <ul class="navigation-list">
3
- {%- assign pages_list = site.html_pages | sort:"nav_order" -%}
4
- {%- for node in pages_list -%}
5
- {%- unless node.nav_exclude -%}
6
- {%- if node.parent == nil -%}
7
- <li class="navigation-list-item
8
- {% if page.url == node.url %} active{% endif %}
9
- {% if node.section %}section-title{% endif %}
10
- ">
11
- {%- if page.parent == node.title or page.grand_parent == node.title -%}
12
- {%- assign first_level_url = node.section_link | node.url | absolute_url -%}
13
- {%- endif -%}
14
- {%- if node.section -%}
15
- <span class="section-title">{{ node.title }}</span>
16
- {%- else -%}
17
- <a href="{{ node.url | absolute_url }}" class="navigation-list-link{% if page.url == node.url %} active{% endif %}">{{ node.title }}</a>
18
- {%- endif -%}
19
- {%- if node.has_children -%}
20
- {%- if node.alphabetical_order -%}
21
- {%- assign children_list = site.html_pages | where: "parent", node.title | sort:"title" -%}
22
- {%- else -%}
23
- {%- assign children_list = site.html_pages | where: "parent", node.title | sort:"nav_order" -%}
24
- {%- endif -%}
25
- <ul class="navigation-list-child-list ">
26
- {%- for child in children_list -%}
27
- <li class="navigation-list-item {% if page.url == child.url or page.parent == child.title %} active{% endif %}">
28
- {%- if page.url == child.url or page.parent == child.title -%}
29
- {%- assign second_level_url = child.url | absolute_url -%}
30
- {%- endif -%}
31
- <a href="{{ child.url | absolute_url }}" class="navigation-list-link{% if page.url == child.url %} active{% endif %}">{{ child.title }}</a>
32
- {%- if child.has_children -%}
33
- {%- assign grand_children_list = site.html_pages | where: "parent", child.title | sort:"nav_order" -%}
34
- <ul class="navigation-list-child-list">
35
- {%- for grand_child in grand_children_list -%}
36
- <li class="navigation-list-item {% if page.url == grand_child.url %} active{% endif %}">
37
- <a href="{{ grand_child.url | absolute_url }}" class="navigation-list-link{% if page.url == grand_child.url %} active{% endif %}">{{ grand_child.title }}</a>
38
- </li>
39
- {%- endfor -%}
40
- </ul>
41
- {%- endif -%}
42
- </li>
43
- {%- endfor -%}
44
- </ul>
45
- {%- endif -%}
46
- </li>
47
- {%- endif -%}
48
- {%- endunless -%}
49
- {%- endfor -%}
50
- </ul>
51
- </nav>