manager 0.0.0 → 0.1.0
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.
- checksums.yaml +4 -4
- data/CHART.html +1270 -0
- data/MANUAL.html +1252 -0
- data/bin/manager +43 -0
- data/examples/array/CHART.html +1376 -0
- data/examples/array/MANUAL.html +1126 -0
- data/examples/array/spec +3438 -0
- data/lib/manager.rb +528 -0
- data/lib/manager/annotation +96 -0
- data/lib/manager/input +189 -0
- data/lib/manager/js +257 -0
- data/lib/manager/refine_module +142 -0
- data/lib/manager/refine_object_mapping +143 -0
- data/lib/manager/refine_test +97 -0
- data/lib/manager/render +1228 -0
- data/lib/manager/spell_check +49 -0
- data/lib/manager/test +404 -0
- data/lib/manager/test_helper +9 -0
- data/license +9 -0
- data/manager.gemspec +21 -0
- data/spec/alternatives_implemented.png +0 -0
- data/spec/alternatives_unimplemented.png +0 -0
- data/spec/annotations.png +0 -0
- data/spec/benchmark_test.png +0 -0
- data/spec/citation.png +0 -0
- data/spec/code_block.png +0 -0
- data/spec/context_module.png +0 -0
- data/spec/documentation +1289 -0
- data/spec/external_link.png +0 -0
- data/spec/image.png +0 -0
- data/spec/list.png +0 -0
- data/spec/long.png +0 -0
- data/spec/main_and_object.png +0 -0
- data/spec/markup.png +0 -0
- data/spec/module_diagram.png +0 -0
- data/spec/navigation.png +0 -0
- data/spec/nested_section_headers.png +0 -0
- data/spec/ruby.png +0 -0
- data/spec/setup_teardown.png +0 -0
- data/spec/short.png +0 -0
- data/spec/signature.png +0 -0
- data/spec/spec +76 -0
- data/spec/spec_example.png +0 -0
- data/spec/table.png +0 -0
- data/spec/test_header.png +0 -0
- data/spec/test_non_unit_spec +184 -0
- data/spec/test_program +71 -0
- data/spec/test_unit_spec +790 -0
- data/spec/tutorial_1.png +0 -0
- data/spec/tutorial_2.png +0 -0
- data/spec/tutorial_3.png +0 -0
- data/spec/tutorial_4.png +0 -0
- data/spec/tutorial_5.png +0 -0
- data/spec/tutorial_6.png +0 -0
- data/spec/tutorial_7.png +0 -0
- data/spec/tutorial_8.png +0 -0
- data/spec/unambiguous_links.png +0 -0
- data/spec/unit_test_failure.png +0 -0
- data/spec/unit_test_raise.png +0 -0
- data/spec/unit_test_receiver.png +0 -0
- data/spec/unit_test_succeed.png +0 -0
- data/spec/unit_test_success.png +0 -0
- data/spec/unit_test_throw.png +0 -0
- data/spec/valid_heading.png +0 -0
- data/spec/with_expr.png +0 -0
- data/spec/without_expr.png +0 -0
- data/theme/2016a.css +670 -0
- data/theme/coderay_github.css +132 -0
- metadata +140 -11
@@ -0,0 +1,96 @@
|
|
1
|
+
#!ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Copyright (c) 2016 sawa
|
5
|
+
|
6
|
+
class Manager
|
7
|
+
class AnnotationExtractor
|
8
|
+
AnnotationLine = /#(?<scope>!{1,2})\s*(?:(?<tag>[^\s:]*):)?\s*(?<text>.+)?/
|
9
|
+
ContinuationOrCommentLine = /^#\s*(?<text>.+)?/
|
10
|
+
ContinuationLine = /^\s+#\s*(?<text>.+)?/
|
11
|
+
BlockCommentStart = /^=begin\s/
|
12
|
+
BlockCommentEnd = /^=end[\s\z]/
|
13
|
+
DebugCommand = /^puts\b|^p\b|\.intercept\b/
|
14
|
+
|
15
|
+
def initialize f
|
16
|
+
#! Annotation and block comment can expand for multiple lines, hence the need of flag.
|
17
|
+
@tag, @block_comment, @io, @f, @l = nil, nil, File.new(f), f, 0
|
18
|
+
@feature = []
|
19
|
+
end
|
20
|
+
def read_upto modul, type, alt, (f, l)
|
21
|
+
#! The reported event might not be directly defining a method, but instead, for example,
|
22
|
+
# aliasing a method name to a method already defined at some other location. These
|
23
|
+
# cases will occur with a combination of a file name and a line number that do not
|
24
|
+
# point toward a forward location relative to the current read point, and hence
|
25
|
+
# can be ignored.
|
26
|
+
return unless f == @f and l > @l
|
27
|
+
read_line until @l == l
|
28
|
+
case @feature.last &.[](1) when :instance, :singleton
|
29
|
+
@feature.pop
|
30
|
+
end
|
31
|
+
case type
|
32
|
+
when :module_end
|
33
|
+
@feature.pop
|
34
|
+
else
|
35
|
+
@feature.push([modul, type, Manager.main_method(alt)])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
def close
|
39
|
+
read_line until @io.eof?
|
40
|
+
@io.close
|
41
|
+
end
|
42
|
+
def read_line
|
43
|
+
@l += 1
|
44
|
+
s = @io.gets
|
45
|
+
return if @feature.empty?
|
46
|
+
case s
|
47
|
+
when AnnotationLine
|
48
|
+
@global = $~[:scope].length == 2
|
49
|
+
@tag = $~[:tag] || Manager.current.counts[:annotation] += 1
|
50
|
+
text = $~[:text] &.strip
|
51
|
+
when DebugCommand
|
52
|
+
@tag = :debug
|
53
|
+
text = nil
|
54
|
+
when BlockCommentStart
|
55
|
+
@tag = :comment
|
56
|
+
@block_comment = true
|
57
|
+
text = nil
|
58
|
+
when BlockCommentEnd
|
59
|
+
@tag = :comment
|
60
|
+
@block_comment = nil
|
61
|
+
text = nil
|
62
|
+
when ContinuationOrCommentLine
|
63
|
+
case @tag
|
64
|
+
when String, Integer
|
65
|
+
text = $~[:text] &.strip
|
66
|
+
else
|
67
|
+
@tag = :comment
|
68
|
+
text = nil
|
69
|
+
end
|
70
|
+
when ContinuationLine
|
71
|
+
case @tag
|
72
|
+
when String, Integer
|
73
|
+
text = $~[:text] &.strip
|
74
|
+
else
|
75
|
+
@tag = nil
|
76
|
+
return
|
77
|
+
end
|
78
|
+
else
|
79
|
+
if @block_comment
|
80
|
+
@tag = :comment
|
81
|
+
text = nil
|
82
|
+
else
|
83
|
+
@tag = nil
|
84
|
+
return
|
85
|
+
end
|
86
|
+
end
|
87
|
+
feature = @tag.is_a?(String) && @global ? [Main, @f, nil] : @feature.last
|
88
|
+
a, s = (Manager.current.annotations[feature] ||= {})[@tag] ||= [[], +""]
|
89
|
+
a.push([@f, text.!.!, @l])
|
90
|
+
if text
|
91
|
+
s.concat(Render::Annotation::Joiner) unless s.empty?
|
92
|
+
s.concat(text)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/lib/manager/input
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
#!ruby
|
2
|
+
#frozen-string-literal: true
|
3
|
+
|
4
|
+
# Copyright (c) 2016 sawa
|
5
|
+
|
6
|
+
class String
|
7
|
+
def code lang = :ruby
|
8
|
+
Manager::Render::UserCode.new(self, lang)
|
9
|
+
end
|
10
|
+
def code! lang = :ruby
|
11
|
+
Manager::Render::DevCode.new(self, lang)
|
12
|
+
end
|
13
|
+
def setup
|
14
|
+
Manager::Setup.new(self, caller_locations.first)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module Manager::MethodSignatureItem
|
19
|
+
def | other
|
20
|
+
unless Manager::MethodSignatureItem === other
|
21
|
+
raise "Expecting a value, exception, or a `Class`: #{other}."
|
22
|
+
end
|
23
|
+
Manager::MethodSignatureAlternatives.new(self, other)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Manager::MethodSignatureValue
|
28
|
+
def initialize obj; @obj = obj end
|
29
|
+
def to_s; "`#{@obj.inspect}`" end
|
30
|
+
include Manager::MethodSignatureItem
|
31
|
+
end
|
32
|
+
|
33
|
+
class Manager::MethodSignatureException
|
34
|
+
def initialize exception; @exception = exception end
|
35
|
+
def to_s; "raise #{@exception.inspect}" end
|
36
|
+
include Manager::MethodSignatureItem
|
37
|
+
end
|
38
|
+
|
39
|
+
class Class
|
40
|
+
include Manager::MethodSignatureItem
|
41
|
+
end
|
42
|
+
|
43
|
+
class Manager::MethodSignatureAlternatives
|
44
|
+
attr_reader :classes
|
45
|
+
def initialize *classes; @classes = classes end
|
46
|
+
def to_s; @classes.map(&:to_s).join(" | ") end
|
47
|
+
def | other
|
48
|
+
unless Manager::MethodSignatureItem === other
|
49
|
+
raise "Expecting a value, exception, or a `Class`: #{other}."
|
50
|
+
end
|
51
|
+
@classes.push(other)
|
52
|
+
self
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
#! Rather than defining the methods in `main` or in a common module and including that module in both `main.singleton_class` and `Module`, repeating this definition directly in `main.singleton_class` and `Module` so as to minimize pollution i.e. avoid poluting the main name space with these methods.
|
57
|
+
|
58
|
+
def self.hide spec
|
59
|
+
Manager.current.hide(spec)
|
60
|
+
end
|
61
|
+
def self.move spec
|
62
|
+
Manager.current.move(spec)
|
63
|
+
end
|
64
|
+
def self.spec feature, *items, coda
|
65
|
+
Manager.current._spec(self, *Manager.validate_feature_call(self, feature, coda), items)
|
66
|
+
end
|
67
|
+
def self.coda; Manager::Coda end
|
68
|
+
def self.value obj
|
69
|
+
Manager::MethodSignatureValue.new(obj)
|
70
|
+
end
|
71
|
+
def self.error klass = RuntimeError
|
72
|
+
unless Class === klass and klass <= Exception
|
73
|
+
raise "Expecting an `Exception` subclass: #{klass}."
|
74
|
+
end
|
75
|
+
Manager::MethodSignatureException.new(klass)
|
76
|
+
end
|
77
|
+
def self.image text, f, **style
|
78
|
+
if style.empty? #!Ruby bug
|
79
|
+
Manager::Render::UserImage.new(text, f)
|
80
|
+
else
|
81
|
+
Manager::Render::UserImage.new(text, f, style)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
def self.image! text, f, **style
|
85
|
+
if style.empty? #!Ruby bug
|
86
|
+
Manager::Render::DevImage.new(text, f)
|
87
|
+
else
|
88
|
+
Manager::Render::DevImage.new(text, f, style)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
def self.teardown; Manager::Render::Teardown end
|
92
|
+
|
93
|
+
#! Unlike the other methods above, this one is not defined on `main.singleton_class` and `Module` because it should be callable from within `receiver.instance_eval{...}` environment inside a setup."
|
94
|
+
def expr exp
|
95
|
+
raise "Expecting a string: `#{exp}`." unless String === exp
|
96
|
+
Manager::Expr.new(exp, caller_locations)
|
97
|
+
end
|
98
|
+
|
99
|
+
class Module
|
100
|
+
def hide spec
|
101
|
+
Manager.current.hide(spec)
|
102
|
+
end
|
103
|
+
def move spec
|
104
|
+
Manager.current.move(spec)
|
105
|
+
end
|
106
|
+
def spec feature, *items, coda
|
107
|
+
print "Reading #{caller_locations.first}:`spec`..."; $stdout.flush
|
108
|
+
Manager.current._spec(self, *Manager.validate_feature_call(self, feature, coda), items)
|
109
|
+
.tap{print "Done\r"; $stdout.flush}
|
110
|
+
end
|
111
|
+
def coda; Manager::Coda end
|
112
|
+
def value obj
|
113
|
+
Manager::MethodSignatureValue.new(obj)
|
114
|
+
end
|
115
|
+
def error klass = RuntimeError
|
116
|
+
unless Class === klass and klass <= Exception
|
117
|
+
raise "Expecting an `Exception` subclass: #{klass}."
|
118
|
+
end
|
119
|
+
Manager::MethodSignatureException.new(klass)
|
120
|
+
end
|
121
|
+
def image text, f, **style
|
122
|
+
if style.empty? #!Ruby bug
|
123
|
+
Manager::Render::UserImage.new(text, f)
|
124
|
+
else
|
125
|
+
Manager::Render::UserImage.new(text, f, style)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
def image! text, f, **style
|
129
|
+
if style.empty? #!Ruby bug
|
130
|
+
Manager::Render::DevImage.new(text, f)
|
131
|
+
else
|
132
|
+
Manager::Render::DevImage.new(text, f, style)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
def teardown; Manager::Render::Teardown end
|
136
|
+
end
|
137
|
+
|
138
|
+
def self.gemspec f
|
139
|
+
f = File.expand_path(f, File.dirname(caller_locations.first.absolute_path))
|
140
|
+
Manager.current.gemspec(f)
|
141
|
+
end
|
142
|
+
def self.manage f
|
143
|
+
Manager.current.manage(f &&
|
144
|
+
File.expand_path(f, File.dirname(caller_locations.first.absolute_path)))
|
145
|
+
end
|
146
|
+
|
147
|
+
class BasicObject
|
148
|
+
using ::Manager::TesterRefinement
|
149
|
+
|
150
|
+
def UT *args, **kargs, &pr
|
151
|
+
::Manager::UnitTest.new(nil, self, [args, kargs, pr])
|
152
|
+
end
|
153
|
+
def BM *args, **kargs, &pr
|
154
|
+
::Manager::Benchmark.new(self, [args, kargs, pr])
|
155
|
+
end
|
156
|
+
UT = ::Manager::SanitizedObject.new
|
157
|
+
RETURN = ::Manager::SanitizedObject.new
|
158
|
+
RECEIVER = ::Manager::SanitizedObject.new
|
159
|
+
OUTPUT = ::Manager::SanitizedObject.new
|
160
|
+
BM = ::Manager::SanitizedObject.new
|
161
|
+
def UT.method_missing method, *args, **kargs, &pr
|
162
|
+
if kargs.empty? #!Ruby bug
|
163
|
+
::Manager::UnitTest.new(nil, nil, nil).__send__(method, *args, &pr)
|
164
|
+
else
|
165
|
+
::Manager::UnitTest.new(nil, nil, nil).__send__(method, *args, **kargs, &pr)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
def RETURN.method_missing method, *args, **kargs, &pr
|
169
|
+
if kargs.empty? #!Ruby bug
|
170
|
+
::Manager::UnitTest.new(:return, nil, nil).__send__(method, *args, &pr)
|
171
|
+
else
|
172
|
+
::Manager::UnitTest.new(:return, nil, nil).__send__(method, *args, **kargs, &pr)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
def RECEIVER.method_missing method, *args, **kargs, &pr
|
176
|
+
if kargs.empty? #!Ruby bug
|
177
|
+
::Manager::UnitTest.new(:receiver, nil, nil).__send__(method, *args, &pr)
|
178
|
+
else
|
179
|
+
::Manager::UnitTest.new(:receiver, nil, nil).__send__(method, *args, **kargs, &pr)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
def OUTPUT.method_missing method, *args, **kargs, &pr
|
183
|
+
if kargs.empty? #!Ruby bug
|
184
|
+
::Manager::UnitTest.new(:output, nil, nil).__send__(method, *args, &pr)
|
185
|
+
else
|
186
|
+
::Manager::UnitTest.new(:output, nil, nil).__send__(method, *args, **kargs, &pr)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
data/lib/manager/js
ADDED
@@ -0,0 +1,257 @@
|
|
1
|
+
//-*-mode: javascript-*-
|
2
|
+
|
3
|
+
// Copyright (c) 2014-2016 sawa
|
4
|
+
|
5
|
+
var main;
|
6
|
+
var scrollMargin;
|
7
|
+
|
8
|
+
// Scroll to the anchor.
|
9
|
+
window.onhashchange = function(e) {
|
10
|
+
// location.href = location.hash;
|
11
|
+
// main.scrollTop -= main.offsetHeight * 0.5 + scrollMargin;
|
12
|
+
main.scrollTop -= scrollMargin;
|
13
|
+
};
|
14
|
+
|
15
|
+
document.body.onload = function() {
|
16
|
+
main = document.getElementById('main');
|
17
|
+
//This line is needed to invoke `window.onhashchange` even when `location.hash`
|
18
|
+
// is the same as the previous load.
|
19
|
+
location.hash = '';
|
20
|
+
//TODO. Import data from webstore.
|
21
|
+
//location.hash =
|
22
|
+
var joinQuery = function(obj, prefix, affix){
|
23
|
+
return prefix + obj.dataset.tags.split(' ').join(affix + ', ' + prefix) + affix;
|
24
|
+
}
|
25
|
+
var tagsumPrefix = '#tagsum-', tagsumAffix = ':not([style="opacity: 0.2;"])';
|
26
|
+
var i, obj, query;
|
27
|
+
query = '.feature:not([style="display: none;"]) .tag.';
|
28
|
+
for(i = 1; obj = document.getElementById('user-feature-navigation' + i); i++) {
|
29
|
+
obj.query = joinQuery(obj, query, '');
|
30
|
+
obj.tagsums = joinQuery(obj, tagsumPrefix, tagsumAffix);
|
31
|
+
initializeNavigation(obj);
|
32
|
+
}
|
33
|
+
for(i = 1; obj = document.getElementById('dev-feature-navigation' + i); i++) {
|
34
|
+
obj.query = joinQuery(obj, query, '');
|
35
|
+
obj.tagsums = joinQuery(obj, tagsumPrefix, tagsumAffix);
|
36
|
+
initializeNavigation(obj);
|
37
|
+
}
|
38
|
+
query = '\
|
39
|
+
.feature:not([style="display: none;"]):not([folded="true"]) \
|
40
|
+
.feature-contents > :not([style="display: none;"]) \
|
41
|
+
.anchor:not([style="display: none;"]) \
|
42
|
+
.tag.';
|
43
|
+
for(i = 1; obj = document.getElementById('anchor-navigation' + i); i++) {
|
44
|
+
obj.query = joinQuery(obj, query, '');
|
45
|
+
obj.tagsums = joinQuery(obj, tagsumPrefix, tagsumAffix);
|
46
|
+
initializeNavigation(obj);
|
47
|
+
}
|
48
|
+
var objs = document.getElementsByClassName('feature');
|
49
|
+
for(var i = 0; i < objs.length; i++) {
|
50
|
+
// TODO. copy from webstore if any.
|
51
|
+
objs[i].hiddenFor = {};
|
52
|
+
// hide(objs[i], Object.keys(objs[i].hiddenFor).length);
|
53
|
+
}
|
54
|
+
switch(document.body.id){
|
55
|
+
case 'user':
|
56
|
+
scrollMargin = 200;
|
57
|
+
// Click "Features" button.
|
58
|
+
document.getElementById('top').children[0].children[1].onclick();
|
59
|
+
break;
|
60
|
+
case 'dev':
|
61
|
+
// Approximates half of line height from experience. TODO: Do it logically.
|
62
|
+
scrollMargin = 200;
|
63
|
+
// Click "Full" button. (Neccessary to do this also for adding `folded` attribute)
|
64
|
+
document.getElementById('top').children[0].children[2].onclick();
|
65
|
+
break;
|
66
|
+
}
|
67
|
+
// Prevents feature toggling.
|
68
|
+
// Overwriting `onclick` does not interfere with linking to `href`; it is different from `onclick`.
|
69
|
+
var objs = document.getElementsByTagName('a');
|
70
|
+
for(var i = 0; i < objs.length; i++) objs[i].onclick = function(e) {e.stopPropagation();};
|
71
|
+
};
|
72
|
+
|
73
|
+
initializeNavigation = function(obj) {
|
74
|
+
obj.features = document.querySelectorAll(obj.query);
|
75
|
+
var sum = obj.features.length;
|
76
|
+
obj.querySelector('.sum').innerText = sum;
|
77
|
+
var excluded = -sum;
|
78
|
+
var objs = document.querySelectorAll(obj.tagsums);
|
79
|
+
for(var i = 0; i < objs.length; i++) excluded += parseInt(objs[i].innerText);
|
80
|
+
obj.querySelector('.excluded').innerText = excluded;
|
81
|
+
var current = obj.querySelector('.current');
|
82
|
+
if(sum == 0) {
|
83
|
+
current.innerText = 1;
|
84
|
+
} else {if(parseInt(current.innerText) > sum
|
85
|
+
) current.innerText = sum;
|
86
|
+
};
|
87
|
+
};
|
88
|
+
|
89
|
+
initializeNavigations = function() {
|
90
|
+
for(var i = 1, obj; obj = document.getElementById('user-feature-navigation' + i); i++
|
91
|
+
) initializeNavigation(obj);
|
92
|
+
for(var i = 1, obj; obj = document.getElementById('dev-feature-navigation' + i); i++
|
93
|
+
) initializeNavigation(obj);
|
94
|
+
for(var i = 1, obj; obj = document.getElementById('anchor-navigation' + i); i++
|
95
|
+
) initializeNavigation(obj);
|
96
|
+
};
|
97
|
+
|
98
|
+
getFeatureNodeFromId = function(id) {
|
99
|
+
var obj = document.getElementById(id);
|
100
|
+
if(!obj) return null;
|
101
|
+
while(true) {
|
102
|
+
if(obj.className == 'feature') return obj;
|
103
|
+
obj = obj.parentNode;
|
104
|
+
if(!obj) return null;
|
105
|
+
}
|
106
|
+
};
|
107
|
+
|
108
|
+
getIdFromObj = function(obj) {
|
109
|
+
while(true) {
|
110
|
+
if(obj.id) return obj.id;
|
111
|
+
obj = obj.parentNode;
|
112
|
+
if(!obj) return null;
|
113
|
+
}
|
114
|
+
};
|
115
|
+
|
116
|
+
hide = function(obj, bool) {obj.style.display = bool ? 'none' : null;};
|
117
|
+
|
118
|
+
inactivate = function(obj, bool) {obj.style.opacity = bool ? 0.2 : null;};
|
119
|
+
|
120
|
+
mark = function(obj, bool) {return obj.marking = bool;};
|
121
|
+
|
122
|
+
toggleMarking = function(obj) {return obj.marking = !obj.marking;};
|
123
|
+
|
124
|
+
hideByTag = function(obj, tag, bool) {
|
125
|
+
if(bool) {obj.hiddenFor[tag] = true;} else {delete obj.hiddenFor[tag];};
|
126
|
+
hide(obj, Object.keys(obj.hiddenFor).length);
|
127
|
+
};
|
128
|
+
|
129
|
+
foldModuleContents = function(obj, bool){
|
130
|
+
obj.firstChild.setAttribute('folded', bool);
|
131
|
+
var objs = obj.childNodes;
|
132
|
+
foldFeatureContents(objs[0], bool);
|
133
|
+
// From the second children.
|
134
|
+
for (var i = 1; i < objs.length; i++) hideByTag(objs[i], 'folded', bool);
|
135
|
+
return bool;
|
136
|
+
};
|
137
|
+
|
138
|
+
foldFeatureContents = function(obj, bool){
|
139
|
+
obj.setAttribute('folded', bool);
|
140
|
+
hide(obj.firstChild.nextSibling, bool);
|
141
|
+
return bool;
|
142
|
+
};
|
143
|
+
|
144
|
+
displayMode = function(bool1, bool2) {
|
145
|
+
var objs = document.getElementsByClassName('module');
|
146
|
+
for(var i = 0; i < objs.length; i++) foldModuleContents(objs[i], mark(objs[i], bool1));
|
147
|
+
// `[onclick]`: Features with `type` `:module_as_constant` are not clickable.
|
148
|
+
// `:not(:first-child)`: Don't fold module headers here.
|
149
|
+
var objs = document.querySelectorAll('.feature[onclick]:not(:first-child)');
|
150
|
+
for(var i = 0; i < objs.length; i++) foldFeatureContents(objs[i], mark(objs[i], bool2));
|
151
|
+
initializeNavigations();
|
152
|
+
};
|
153
|
+
|
154
|
+
toggleModuleContents = function(feature) {
|
155
|
+
var module = feature.parentNode;
|
156
|
+
var bool = foldModuleContents(module, toggleMarking(module));
|
157
|
+
if(bool) {
|
158
|
+
module.scrollIntoView();
|
159
|
+
window.onhashchange();
|
160
|
+
}
|
161
|
+
initializeNavigations();
|
162
|
+
};
|
163
|
+
|
164
|
+
toggleFeatureContents = function(feature) {
|
165
|
+
var bool = foldFeatureContents(feature, toggleMarking(feature));
|
166
|
+
if(bool) {
|
167
|
+
feature.scrollIntoView();
|
168
|
+
window.onhashchange();
|
169
|
+
}
|
170
|
+
initializeNavigations();
|
171
|
+
};
|
172
|
+
|
173
|
+
toggleUserItems = function(button) {
|
174
|
+
// recordScrollPosition();
|
175
|
+
var bool = toggleMarking(button);
|
176
|
+
inactivate(button, bool);
|
177
|
+
objs = document.getElementsByClassName('user-item');
|
178
|
+
for(i = 0; i < objs.length; i++) hide(objs[i], bool);
|
179
|
+
initializeNavigations();
|
180
|
+
// resumeScrollPosition();
|
181
|
+
};
|
182
|
+
|
183
|
+
toggleFeatures = function(button, tag, navigation) {
|
184
|
+
// recordScrollPosition();
|
185
|
+
var bool = toggleMarking(button);
|
186
|
+
inactivate(button, bool);
|
187
|
+
inactivate(document.getElementById('tagsum-' + tag), bool);
|
188
|
+
for(var i = 1, obj; obj = getFeatureNodeFromId(tag + i); i ++) hideByTag(obj, tag, bool);
|
189
|
+
navigation = document.getElementById(navigation);
|
190
|
+
initializeNavigations();
|
191
|
+
// resumeScrollPosition();
|
192
|
+
};
|
193
|
+
|
194
|
+
toggleAnchors = function(button, tag, navigation) {
|
195
|
+
// recordScrollPosition();
|
196
|
+
var bool = toggleMarking(button);
|
197
|
+
inactivate(button, bool);
|
198
|
+
inactivate(document.getElementById('tagsum-' + tag), bool);
|
199
|
+
for(var i = 1, obj; obj = document.getElementById(tag + i); i ++) hide(obj, bool);
|
200
|
+
navigation = document.getElementById(navigation);
|
201
|
+
initializeNavigation(navigation);
|
202
|
+
// resumeScrollPosition();
|
203
|
+
};
|
204
|
+
|
205
|
+
navigateTag = function(navigation, d) {
|
206
|
+
var n = navigation.features.length;
|
207
|
+
if(n == 0) return;
|
208
|
+
var old = document.getElementById('current');
|
209
|
+
if(old) old.removeAttribute('id');
|
210
|
+
var current = navigation.querySelector('.current');
|
211
|
+
current.id = 'current';
|
212
|
+
var i = parseInt(current.innerText) + d;
|
213
|
+
if(i < 1) i = 1;
|
214
|
+
if(i > n) i = n;
|
215
|
+
current.innerText = i;
|
216
|
+
location.hash = getIdFromObj(navigation.features[i - 1]);
|
217
|
+
};
|
218
|
+
|
219
|
+
//var lastToggled =
|
220
|
+
//var lastViewPort =
|
221
|
+
recordScrollPosition = function() {
|
222
|
+
// main.scrollTop = navigation.features[i - 1].offsetTop - main.offsetTop;
|
223
|
+
/*
|
224
|
+
foo = function(obj) {
|
225
|
+
var ref = window.scrollY - window.pageYOffset + document.documentElement.clientTop;
|
226
|
+
var checkChildDivs = function() {
|
227
|
+
var children = obj.childNodes;
|
228
|
+
if (children.length) {[].forEach.call(children, function(e, i, a) {
|
229
|
+
if (e.toString() === "[object HTMLDivElement]") {
|
230
|
+
// the top of the div relative to the document
|
231
|
+
// minus the height of window hidden above the top of the screen
|
232
|
+
var top = e.getBoundingClientRect().top;
|
233
|
+
// top and bottom posns relative to the top of the screen
|
234
|
+
// the top and bottom distances of the element relative to the top of the screen
|
235
|
+
// the div overlaps the screen top
|
236
|
+
if ((top <= ref) && (ref <= top + e.offsetHeight)) {
|
237
|
+
obj = e;
|
238
|
+
checkChildDivs();
|
239
|
+
return false;
|
240
|
+
}
|
241
|
+
}
|
242
|
+
});}
|
243
|
+
};
|
244
|
+
checkChildDivs();
|
245
|
+
return obj;
|
246
|
+
};
|
247
|
+
*/
|
248
|
+
};
|
249
|
+
|
250
|
+
resumeScrollPosition = function() {
|
251
|
+
};
|
252
|
+
|
253
|
+
coverage = function(obj){
|
254
|
+
alert("Sorry, this function is not implemented.");
|
255
|
+
// alert(obj.nextSibling.contentDocument.querySelector('body').innerText);
|
256
|
+
// var f = obj.dataset.file;
|
257
|
+
};
|