jsduck 5.0.0.beta01 → 5.0.0.beta2

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 (95) hide show
  1. data/.travis.yml +1 -0
  2. data/README.md +6 -32
  3. data/Rakefile +5 -5
  4. data/bin/jsduck +0 -1
  5. data/js-classes/String.js +3 -5
  6. data/jsduck.gemspec +3 -2
  7. data/lib/jsduck/aggregator.rb +1 -3
  8. data/lib/jsduck/app.rb +2 -2
  9. data/lib/jsduck/categories/file.rb +0 -6
  10. data/lib/jsduck/class.rb +1 -2
  11. data/lib/jsduck/doc/parser.rb +12 -5
  12. data/lib/jsduck/doc/scanner.rb +6 -0
  13. data/lib/jsduck/doc/standard_tag_parser.rb +10 -5
  14. data/lib/jsduck/doc/subproperties.rb +9 -2
  15. data/lib/jsduck/docs_code_comparer.rb +20 -7
  16. data/lib/jsduck/exporter/app.rb +18 -13
  17. data/lib/jsduck/exporter/full.rb +18 -21
  18. data/lib/jsduck/format/doc.rb +0 -1
  19. data/lib/jsduck/format/html_stack.rb +1 -2
  20. data/lib/jsduck/format/subproperties.rb +2 -2
  21. data/lib/jsduck/inline/auto_link.rb +1 -1
  22. data/lib/jsduck/inline/img.rb +1 -1
  23. data/lib/jsduck/inline/link.rb +4 -6
  24. data/lib/jsduck/inline/video.rb +1 -2
  25. data/lib/jsduck/js/ast.rb +1 -1
  26. data/lib/jsduck/js/esprima.rb +24 -9
  27. data/lib/jsduck/logger.rb +50 -12
  28. data/lib/jsduck/members_index.rb +1 -2
  29. data/lib/jsduck/merger.rb +20 -2
  30. data/lib/jsduck/options.rb +125 -24
  31. data/lib/jsduck/process/accessors.rb +21 -8
  32. data/lib/jsduck/process/enums.rb +2 -3
  33. data/lib/jsduck/process/ext4_events.rb +2 -1
  34. data/lib/jsduck/process/global_members.rb +1 -2
  35. data/lib/jsduck/process/importer.rb +2 -6
  36. data/lib/jsduck/process/inherit_class.rb +58 -0
  37. data/lib/jsduck/process/inherit_doc.rb +6 -175
  38. data/lib/jsduck/process/inherit_members.rb +257 -0
  39. data/lib/jsduck/process/lint.rb +18 -7
  40. data/lib/jsduck/process/overrides.rb +1 -2
  41. data/lib/jsduck/render/class.rb +1 -1
  42. data/lib/jsduck/tag/alias.rb +2 -1
  43. data/lib/jsduck/tag/alternate_class_names.rb +1 -0
  44. data/lib/jsduck/tag/aside.rb +3 -3
  45. data/lib/jsduck/tag/author.rb +18 -3
  46. data/lib/jsduck/tag/autodetected.rb +21 -0
  47. data/lib/jsduck/tag/boolean_tag.rb +1 -1
  48. data/lib/jsduck/tag/cfg.rb +7 -3
  49. data/lib/jsduck/tag/class.rb +1 -1
  50. data/lib/jsduck/tag/class_list_tag.rb +1 -1
  51. data/lib/jsduck/tag/constructor.rb +1 -1
  52. data/lib/jsduck/tag/css_var.rb +1 -1
  53. data/lib/jsduck/tag/default.rb +1 -1
  54. data/lib/jsduck/tag/deprecated_tag.rb +1 -1
  55. data/lib/jsduck/tag/docauthor.rb +2 -0
  56. data/lib/jsduck/tag/enum.rb +2 -2
  57. data/lib/jsduck/tag/event.rb +1 -1
  58. data/lib/jsduck/tag/extends.rb +1 -1
  59. data/lib/jsduck/tag/ftype.rb +2 -1
  60. data/lib/jsduck/tag/inheritdoc.rb +1 -1
  61. data/lib/jsduck/tag/localdoc.rb +33 -0
  62. data/lib/jsduck/tag/markdown.rb +1 -1
  63. data/lib/jsduck/tag/member.rb +1 -1
  64. data/lib/jsduck/tag/method.rb +1 -1
  65. data/lib/jsduck/tag/mixins.rb +1 -0
  66. data/lib/jsduck/tag/override.rb +1 -1
  67. data/lib/jsduck/tag/param.rb +16 -5
  68. data/lib/jsduck/tag/preventable.rb +1 -1
  69. data/lib/jsduck/tag/property.rb +7 -3
  70. data/lib/jsduck/tag/ptype.rb +2 -1
  71. data/lib/jsduck/tag/requires.rb +1 -0
  72. data/lib/jsduck/tag/return.rb +2 -1
  73. data/lib/jsduck/tag/since.rb +1 -5
  74. data/lib/jsduck/tag/tag.rb +21 -12
  75. data/lib/jsduck/tag/throws.rb +2 -1
  76. data/lib/jsduck/tag/type.rb +2 -2
  77. data/lib/jsduck/tag/uses.rb +1 -0
  78. data/lib/jsduck/tag/xtype.rb +2 -1
  79. data/lib/jsduck/tag_loader.rb +26 -15
  80. data/lib/jsduck/tag_registry.rb +20 -11
  81. data/lib/jsduck/web/css.rb +22 -0
  82. data/lib/jsduck/web/data.rb +50 -0
  83. data/lib/jsduck/web/icons.rb +31 -0
  84. data/lib/jsduck/web/index_html.rb +88 -0
  85. data/lib/jsduck/web/search.rb +148 -0
  86. data/lib/jsduck/{source/writer.rb → web/source.rb} +2 -2
  87. data/lib/jsduck/web/template.rb +52 -0
  88. data/lib/jsduck/web/writer.rb +84 -0
  89. metadata +513 -488
  90. data/lib/jsduck/app_data.rb +0 -41
  91. data/lib/jsduck/icons.rb +0 -29
  92. data/lib/jsduck/index_html.rb +0 -84
  93. data/lib/jsduck/search_data.rb +0 -146
  94. data/lib/jsduck/template_dir.rb +0 -50
  95. data/lib/jsduck/web_writer.rb +0 -87
@@ -40,14 +40,26 @@ module JsDuck
40
40
  # print warning for each class or public member with no name
41
41
  def warn_no_doc
42
42
  @relations.each do |cls|
43
- if cls[:doc] == ""
43
+
44
+ if cls[:doc] == "" && !cls[:private]
44
45
  warn(:no_doc, "No documentation for #{cls[:name]}", cls)
45
46
  end
46
- end
47
- each_member do |member|
48
- if member[:doc] == "" && !member[:private] && !member[:hide] && !JsDuck::Class.constructor?(member)
49
- warn(:no_doc, "No documentation for #{member[:owner]}##{member[:name]}", member)
47
+
48
+ cls.all_local_members.each do |member|
49
+ if !member[:private] && !member[:hide] && !JsDuck::Class.constructor?(member)
50
+ if member[:doc] == ""
51
+ warn(:no_doc, "No documentation for #{member[:owner]}##{member[:name]}", member)
52
+ end
53
+
54
+ (member[:params] || []).each do |p|
55
+ if p[:doc] == ""
56
+ warn(:no_doc, "No documentation for parameter #{p[:name]} of #{member[:owner]}##{member[:name]}", member)
57
+ end
58
+ end
59
+
60
+ end
50
61
  end
62
+
51
63
  end
52
64
  end
53
65
 
@@ -125,8 +137,7 @@ module JsDuck
125
137
 
126
138
  # Prints warning + filename and linenumber from doc-context
127
139
  def warn(type, msg, member)
128
- context = member[:files][0]
129
- Logger.warn(type, msg, context[:filename], context[:linenr])
140
+ Logger.warn(type, msg, member[:files][0])
130
141
  end
131
142
 
132
143
  end
@@ -37,8 +37,7 @@ module JsDuck
37
37
  def process(override)
38
38
  target = @classes_hash[override[:override]]
39
39
  unless target
40
- ctx = override[:files][0]
41
- return Logger.warn(:extend, "Class #{override[:override]} not found", ctx[:filename], ctx[:linenr])
40
+ return Logger.warn(:extend, "Class #{override[:override]} not found", override[:files][0])
42
41
  end
43
42
 
44
43
  # Combine comments of classes
@@ -45,7 +45,7 @@ module JsDuck
45
45
  end
46
46
 
47
47
  def render_section(sec)
48
- members = @cls[:members][sec[:name]] + @cls[:statics][sec[:name]]
48
+ members = @cls[:members].find_all {|m| m[:tagname] == sec[:name] }
49
49
 
50
50
  # Skip rendering empty sections
51
51
  return [] if members.length == 0
@@ -6,6 +6,7 @@ module JsDuck::Tag
6
6
  def initialize
7
7
  @pattern = "alias"
8
8
  @tagname = :aliases
9
+ @repeatable = true
9
10
  @ext_define_pattern = "alias"
10
11
  @ext_define_default = {:aliases => []}
11
12
  @merge_context = :class
@@ -14,7 +15,7 @@ module JsDuck::Tag
14
15
  # For backwards compatibility decide whether the @alias was used
15
16
  # as @inheritdoc (@alias used to have the meaning of @inheritdoc
16
17
  # before) or as a real Ext4 style alias definition.
17
- def parse_doc(p)
18
+ def parse_doc(p, pos)
18
19
  if p.look(/([\w.]+)?#\w+/)
19
20
  parse_as_inheritdoc(p)
20
21
  else
@@ -5,6 +5,7 @@ module JsDuck::Tag
5
5
  def initialize
6
6
  @pattern = ["alternateClassName", "alternateClassNames"]
7
7
  @tagname = :alternateClassNames
8
+ @repeatable = true
8
9
  @ext_define_pattern = "alternateClassName"
9
10
  @ext_define_default = {:alternateClassNames => []}
10
11
  @merge_context = :class
@@ -6,11 +6,12 @@ module JsDuck::Tag
6
6
  def initialize
7
7
  @pattern = "aside"
8
8
  @tagname = :aside
9
+ @repeatable = true
9
10
  @html_position = POS_ASIDE
10
11
  end
11
12
 
12
13
  # Parses: @aside [ guide | video| example ] name
13
- def parse_doc(p)
14
+ def parse_doc(p, pos)
14
15
  {
15
16
  :tagname => :aside,
16
17
  :type => aside_type(p),
@@ -62,8 +63,7 @@ module JsDuck::Tag
62
63
  end
63
64
 
64
65
  def warn(msg, context)
65
- file = context[:files][0]
66
- JsDuck::Logger.warn(:aside, msg, file[:filename], file[:linenr])
66
+ JsDuck::Logger.warn(:aside, msg, context[:files][0])
67
67
  nil
68
68
  end
69
69
 
@@ -1,15 +1,30 @@
1
1
  require "jsduck/tag/tag"
2
2
 
3
3
  module JsDuck::Tag
4
+ # Author tag gets processed, but no output gets created. Users of
5
+ # JSDuck may override this tag to make it print the names of
6
+ # authors.
4
7
  class Author < Tag
5
8
  def initialize
6
9
  @pattern = "author"
10
+ @tagname = :author
11
+ @repeatable = true
7
12
  end
8
13
 
9
14
  # @author Name of Author <email@example.com> ...
10
- # Everything until the end of line gets just ignored.
11
- def parse_doc(p)
12
- p.match(/.*$/)
15
+ def parse_doc(p, pos)
16
+ name = p.match(/[^<\n]*/).strip
17
+ if p.look(/</)
18
+ p.match(/</)
19
+ email = p.match(/[^>\n]*/)
20
+ p.match(/>/)
21
+ end
22
+
23
+ return {:tagname => @tagname, :name => name, :email => email}
24
+ end
25
+
26
+ def process_doc(context, tags, pos)
27
+ context[@tagname] = tags
13
28
  end
14
29
  end
15
30
  end
@@ -0,0 +1,21 @@
1
+ require "jsduck/tag/tag"
2
+ require "jsduck/docs_code_comparer"
3
+
4
+ module JsDuck::Tag
5
+ # There is no @autodetected tag.
6
+ #
7
+ # This tag class exists to take care of the merging of :autodetected
8
+ # field.
9
+ class Autodetected < Tag
10
+ def initialize
11
+ @tagname = :autodetected
12
+ @merge_context = [:class, :member]
13
+ end
14
+
15
+ def merge(h, docs, code)
16
+ if docs[:autodetected] || code[:autodetected]
17
+ h[:autodetected] = (code[:autodetected] || {}).merge(docs[:autodetected] || {})
18
+ end
19
+ end
20
+ end
21
+ end
@@ -12,7 +12,7 @@ module JsDuck::Tag
12
12
  end
13
13
 
14
14
  # Parses just the name of the tag.
15
- def parse_doc(p)
15
+ def parse_doc(p, pos)
16
16
  {:tagname => @tagname}
17
17
  end
18
18
 
@@ -6,6 +6,7 @@ module JsDuck::Tag
6
6
  def initialize
7
7
  @pattern = "cfg"
8
8
  @tagname = :cfg
9
+ @repeatable = true
9
10
  @member_type = {
10
11
  :name => :cfg,
11
12
  :category => :property_like,
@@ -20,7 +21,7 @@ module JsDuck::Tag
20
21
  end
21
22
 
22
23
  # @cfg {Type} [name=default] (required) ...
23
- def parse_doc(p)
24
+ def parse_doc(p, pos)
24
25
  tag = p.standard_tag({:tagname => :cfg, :type => true, :name => true})
25
26
  tag[:optional] = false if parse_required(p)
26
27
  tag[:doc] = :multiline
@@ -33,13 +34,16 @@ module JsDuck::Tag
33
34
 
34
35
  def process_doc(h, tags, pos)
35
36
  p = tags[0]
36
- h[:name] = p[:name]
37
37
  h[:type] = p[:type]
38
38
  h[:default] = p[:default]
39
- h[:properties] = JsDuck::Doc::Subproperties.nest(tags, pos)[0][:properties]
40
39
  h[:required] = true if p[:optional] == false
40
+
41
41
  # Documentation after the first @cfg is part of the top-level docs.
42
42
  h[:doc] += p[:doc]
43
+
44
+ nested = JsDuck::Doc::Subproperties.nest(tags, pos)[0]
45
+ h[:properties] = nested[:properties]
46
+ h[:name] = nested[:name]
43
47
  end
44
48
  end
45
49
  end
@@ -9,7 +9,7 @@ module JsDuck::Tag
9
9
  end
10
10
 
11
11
  # @class name
12
- def parse_doc(p)
12
+ def parse_doc(p, pos)
13
13
  {
14
14
  :tagname => :class,
15
15
  :name => p.ident_chain,
@@ -13,7 +13,7 @@ module JsDuck::Tag
13
13
  # #parse_ext_define to work.
14
14
  #
15
15
  class ClassListTag < Tag
16
- def parse_doc(p)
16
+ def parse_doc(p, pos)
17
17
  {
18
18
  :tagname => @tagname,
19
19
  :classes => classname_list(p),
@@ -8,7 +8,7 @@ module JsDuck::Tag
8
8
  end
9
9
 
10
10
  # @constructor
11
- def parse_doc(p)
11
+ def parse_doc(p, pos)
12
12
  {:tagname => :constructor, :doc => :multiline}
13
13
  end
14
14
 
@@ -15,7 +15,7 @@ module JsDuck::Tag
15
15
  end
16
16
 
17
17
  # @var {Type} [name=default] ...
18
- def parse_doc(p)
18
+ def parse_doc(p, pos)
19
19
  p.standard_tag({:tagname => :css_var, :type => true, :name => true})
20
20
  end
21
21
 
@@ -19,7 +19,7 @@ module JsDuck::Tag
19
19
  end
20
20
 
21
21
  def merge(h, docs, code)
22
- h[:default] = JsDuck::DocsCodeComparer.merge_if_matches(:default, docs, code)
22
+ JsDuck::DocsCodeComparer.merge_if_matches(h, :default, docs, code)
23
23
  end
24
24
 
25
25
  def to_html(m)
@@ -25,7 +25,7 @@ module JsDuck::Tag
25
25
  end
26
26
  end
27
27
 
28
- def parse_doc(p)
28
+ def parse_doc(p, pos)
29
29
  {
30
30
  :tagname => @tagname,
31
31
  :version => p.match(/[0-9.]+/),
@@ -4,7 +4,9 @@ module JsDuck::Tag
4
4
  # Exactly the same as @author tag - it's simply ignored.
5
5
  class Docauthor < Author
6
6
  def initialize
7
+ super
7
8
  @pattern = "docauthor"
9
+ @tagname = :docauthor
8
10
  end
9
11
  end
10
12
  end
@@ -18,7 +18,7 @@ module JsDuck::Tag
18
18
  end
19
19
 
20
20
  # @enum {Type} [name=default] ...
21
- def parse_doc(p)
21
+ def parse_doc(p, pos)
22
22
  enum = p.standard_tag({:tagname => :enum, :type => true, :name => true})
23
23
 
24
24
  # @enum is a special case of class, so we also generate a class
@@ -46,7 +46,7 @@ module JsDuck::Tag
46
46
 
47
47
  def to_html(cls)
48
48
  if cls[:enum][:doc_only]
49
- first = cls[:members][:property][0] || {:name => 'foo', :default => '"foo"'}
49
+ first = cls[:members][0] || {:name => 'foo', :default => '"foo"'}
50
50
  [
51
51
  "<div class='rounded-box enum-box'>",
52
52
  "<p><strong>ENUM:</strong> ",
@@ -14,7 +14,7 @@ module JsDuck::Tag
14
14
  end
15
15
 
16
16
  # @event name ...
17
- def parse_doc(p)
17
+ def parse_doc(p, pos)
18
18
  {
19
19
  :tagname => :event,
20
20
  :name => p.ident,
@@ -14,7 +14,7 @@ module JsDuck::Tag
14
14
  # @extends classname
15
15
  # or
16
16
  # @extends {classname}
17
- def parse_doc(p)
17
+ def parse_doc(p, pos)
18
18
  if p.match(/\{/)
19
19
  cls = p.ident_chain
20
20
  p.match(/\}/)
@@ -4,10 +4,11 @@ module JsDuck::Tag
4
4
  class Ftype < Xtype
5
5
  def initialize
6
6
  @pattern = "ftype"
7
+ @repeatable = true
7
8
  end
8
9
 
9
10
  # @ftype name
10
- def parse_doc(p)
11
+ def parse_doc(p, pos)
11
12
  {
12
13
  :tagname => :aliases,
13
14
  :name => parse_alias_shorthand(p, "feature")
@@ -9,7 +9,7 @@ module JsDuck::Tag
9
9
  end
10
10
 
11
11
  # @inheritdoc class.name#static-type-member
12
- def parse_doc(p)
12
+ def parse_doc(p, pos)
13
13
  parse_as_inheritdoc(p)
14
14
  end
15
15
 
@@ -0,0 +1,33 @@
1
+ require "jsduck/tag/tag"
2
+ require 'jsduck/format/shortener'
3
+
4
+ module JsDuck::Tag
5
+ # Non-inheritable documentation
6
+ class Localdoc < Tag
7
+ def initialize
8
+ @pattern = "localdoc"
9
+ @tagname = :localdoc
10
+ @html_position = POS_LOCALDOC
11
+ end
12
+
13
+ def parse_doc(p, pos)
14
+ {
15
+ :tagname => :localdoc,
16
+ :doc => :multiline,
17
+ }
18
+ end
19
+
20
+ def process_doc(m, tags, pos)
21
+ m[:localdoc] = tags.map {|t| t[:doc] }.join("\n\n")
22
+ end
23
+
24
+ def format(m, formatter)
25
+ m[:localdoc] = formatter.format(m[:localdoc])
26
+ end
27
+
28
+ def to_html(m)
29
+ m[:localdoc]
30
+ end
31
+
32
+ end
33
+ end
@@ -7,7 +7,7 @@ module JsDuck::Tag
7
7
  end
8
8
 
9
9
  # @markdown
10
- def parse_doc(p)
10
+ def parse_doc(p, pos)
11
11
  # Just completely ignore this tag.
12
12
  end
13
13
  end
@@ -10,7 +10,7 @@ module JsDuck::Tag
10
10
  end
11
11
 
12
12
  # @member classname
13
- def parse_doc(p)
13
+ def parse_doc(p, pos)
14
14
  {
15
15
  :tagname => :owner,
16
16
  :owner => p.ident_chain,
@@ -19,7 +19,7 @@ module JsDuck::Tag
19
19
  end
20
20
 
21
21
  # @method name ...
22
- def parse_doc(p)
22
+ def parse_doc(p, pos)
23
23
  {
24
24
  :tagname => :method,
25
25
  :name => p.ident,
@@ -5,6 +5,7 @@ module JsDuck::Tag
5
5
  def initialize
6
6
  @pattern = ["mixin", "mixins"]
7
7
  @tagname = :mixins
8
+ @repeatable = true
8
9
  @ext_define_pattern = "mixins"
9
10
  @ext_define_default = {:mixins => []}
10
11
  end
@@ -10,7 +10,7 @@ module JsDuck::Tag
10
10
  end
11
11
 
12
12
  # @override nameOfOverride
13
- def parse_doc(p)
13
+ def parse_doc(p, pos)
14
14
  if classname = p.ident_chain
15
15
  {
16
16
  :tagname => :override,
@@ -9,12 +9,13 @@ module JsDuck::Tag
9
9
  def initialize
10
10
  @pattern = "param"
11
11
  @tagname = :params
12
+ @repeatable = true
12
13
  @merge_context = :method_like
13
14
  @html_position = POS_PARAM
14
15
  end
15
16
 
16
17
  # @param {Type} [name=default] (optional) ...
17
- def parse_doc(p)
18
+ def parse_doc(p, pos)
18
19
  tag = p.standard_tag({:tagname => :params, :type => true, :name => true})
19
20
  tag[:optional] = true if parse_optional(p)
20
21
  tag[:doc] = :multiline
@@ -31,6 +32,10 @@ module JsDuck::Tag
31
32
 
32
33
  def merge(h, docs, code)
33
34
  h[:params] = merge_params(docs, code, h[:files].first)
35
+
36
+ if only_autodetected_params?(docs, code)
37
+ JsDuck::DocsCodeComparer.mark_autodetected(h, :params)
38
+ end
34
39
  end
35
40
 
36
41
  def format(m, formatter)
@@ -43,6 +48,10 @@ module JsDuck::Tag
43
48
 
44
49
  private
45
50
 
51
+ def only_autodetected_params?(docs, code)
52
+ (docs[:params] || []).length == 0 && (code[:params] || []).length > 0
53
+ end
54
+
46
55
  def merge_params(docs, code, file)
47
56
  explicit = docs[:params] || []
48
57
  implicit = JsDuck::DocsCodeComparer.matches?(docs, code) ? (code[:params] || []) : []
@@ -50,19 +59,21 @@ module JsDuck::Tag
50
59
  im_len = implicit.length
51
60
 
52
61
  if ex_len == 0 || im_len == 0
53
- # Skip
62
+ # Skip when either no implicit or explicit params
63
+ elsif ex_len != im_len && explicit.last[:type] =~ /\.\.\.$/
64
+ # Skip when vararg params are in play.
54
65
  elsif ex_len < im_len
55
66
  # Warn when less parameters documented than found from code.
56
- JsDuck::Logger.warn(:param_count, "Detected #{im_len} params, but only #{ex_len} documented.", file[:filename], file[:linenr])
67
+ JsDuck::Logger.warn(:param_count, "Detected #{im_len} params, but only #{ex_len} documented.", file)
57
68
  elsif ex_len > im_len
58
69
  # Warn when more parameters documented than found from code.
59
- JsDuck::Logger.warn(:param_count, "Detected #{im_len} params, but #{ex_len} documented.", file[:filename], file[:linenr])
70
+ JsDuck::Logger.warn(:param_count, "Detected #{im_len} params, but #{ex_len} documented.", file)
60
71
  elsif implicit.map {|p| p[:name] } != explicit.map {|p| p[:name] }
61
72
  # Warn when parameter names don't match up.
62
73
  ex_names = explicit.map {|p| p[:name] }
63
74
  im_names = implicit.map {|p| p[:name] }
64
75
  str = ex_names.zip(im_names).map {|p| ex, im = p; ex == im ? ex : (ex||"")+"/"+(im||"") }.join(", ")
65
- JsDuck::Logger.warn(:param_count, "Documented and auto-detected params don't match: #{str}", file[:filename], file[:linenr])
76
+ JsDuck::Logger.warn(:param_count, "Documented and auto-detected params don't match: #{str}", file)
66
77
  end
67
78
 
68
79
  # Override implicit parameters with explicit ones