@breakside/jskit 2026.9.0 → 2026.11.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.
Files changed (73) hide show
  1. package/Frameworks/DOM.jsframework/Info.json +2 -2
  2. package/Frameworks/DOM.jsframework/io.breakside.JSKit.DOM-bundle.js +2 -2
  3. package/Frameworks/FontKit.jsframework/Info.json +2 -2
  4. package/Frameworks/FontKit.jsframework/io.breakside.JSKit.FontKit-bundle.js +2 -2
  5. package/Frameworks/Foundation.jsframework/Info.json +2 -2
  6. package/Frameworks/Foundation.jsframework/JS/JSColor.js +5 -0
  7. package/Frameworks/Foundation.jsframework/JS/JSNodeHTTPClient.js +34 -14
  8. package/Frameworks/Foundation.jsframework/JS/JSNodeURLSessionDataTask.js +2 -2
  9. package/Frameworks/Foundation.jsframework/JS/JSPath.js +482 -49
  10. package/Frameworks/Foundation.jsframework/JS/JSSpec.js +5 -1
  11. package/Frameworks/Foundation.jsframework/JS/JSURLRequest.js +3 -0
  12. package/Frameworks/Foundation.jsframework/JS/JSZip.js +155 -1
  13. package/Frameworks/Foundation.jsframework/JS/String+JS.js +78 -2
  14. package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
  15. package/Frameworks/SecurityKit.jsframework/Info.json +2 -2
  16. package/Frameworks/SecurityKit.jsframework/io.breakside.JSKit.SecurityKit-bundle.js +2 -2
  17. package/Info.json +2 -2
  18. package/Node/DocCommand.js +5 -2
  19. package/Node/Docs/DocClass.js +40 -3
  20. package/Node/Docs/DocComponent.js +32 -5
  21. package/Node/Docs/DocDictionaryProperty.js +10 -2
  22. package/Node/Docs/DocEnum.js +35 -2
  23. package/Node/Docs/DocEnumOption.js +5 -2
  24. package/Node/Docs/DocExtension.js +130 -0
  25. package/Node/Docs/DocFunction.js +10 -2
  26. package/Node/Docs/DocMethod.js +3 -0
  27. package/Node/Docs/DocProperty.js +13 -2
  28. package/Node/Docs/DocProtocol.js +5 -1
  29. package/Node/Docs/DocSpec.js +5 -1
  30. package/Node/Docs/DocSpecProperty.js +10 -2
  31. package/Node/Docs/DocTopicBasedComponent.js +75 -65
  32. package/Node/Documentation.js +83 -6
  33. package/Node/HTMLBuilder.js +3 -1
  34. package/Node/HTMLProjectServer.js +40 -2
  35. package/Node/Markdown.js +2 -2
  36. package/Node/io.breakside.jskit-bundle.js +4 -4
  37. package/Node/jskit +1 -0
  38. package/Resources/doc-default.css +3 -11
  39. package/Root/Frameworks/APIKit/Info.yaml +1 -1
  40. package/Root/Frameworks/APIKitTesting/Info.yaml +1 -1
  41. package/Root/Frameworks/AuthKit/Info.yaml +1 -1
  42. package/Root/Frameworks/CSSOM/Info.yaml +1 -1
  43. package/Root/Frameworks/ChartKit/Info.yaml +1 -1
  44. package/Root/Frameworks/ConferenceKit/Info.yaml +1 -1
  45. package/Root/Frameworks/DBKit/Info.yaml +1 -1
  46. package/Root/Frameworks/DOM/Info.yaml +1 -1
  47. package/Root/Frameworks/Dispatch/Info.yaml +1 -1
  48. package/Root/Frameworks/FontKit/Info.yaml +1 -1
  49. package/Root/Frameworks/Foundation/Info.yaml +1 -1
  50. package/Root/Frameworks/Foundation/JSColor.js +5 -0
  51. package/Root/Frameworks/Foundation/JSNodeHTTPClient.js +34 -14
  52. package/Root/Frameworks/Foundation/JSNodeURLSessionDataTask.js +2 -2
  53. package/Root/Frameworks/Foundation/JSPath.js +482 -49
  54. package/Root/Frameworks/Foundation/JSSpec.js +5 -1
  55. package/Root/Frameworks/Foundation/JSURLRequest.js +3 -0
  56. package/Root/Frameworks/Foundation/JSZip.js +155 -1
  57. package/Root/Frameworks/Foundation/String+JS.js +78 -2
  58. package/Root/Frameworks/ImageKit/Info.yaml +1 -1
  59. package/Root/Frameworks/MediaKit/Info.yaml +1 -1
  60. package/Root/Frameworks/MediaKitUI/Info.yaml +1 -1
  61. package/Root/Frameworks/NotificationKit/Info.yaml +1 -1
  62. package/Root/Frameworks/PDFKit/Info.yaml +1 -1
  63. package/Root/Frameworks/QRKit/Info.yaml +1 -1
  64. package/Root/Frameworks/SearchKit/Info.yaml +1 -1
  65. package/Root/Frameworks/SecurityKit/Info.yaml +1 -1
  66. package/Root/Frameworks/ServerKit/Info.yaml +1 -1
  67. package/Root/Frameworks/ServerKitTesting/Info.yaml +1 -1
  68. package/Root/Frameworks/TestKit/Info.yaml +1 -1
  69. package/Root/Frameworks/UIKit/Info.yaml +1 -1
  70. package/Root/Frameworks/UIKit/UIListView.js +11 -3
  71. package/Root/Frameworks/UIKit/UIOutlineView.js +65 -5
  72. package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
  73. package/package.json +1 -1
@@ -35,6 +35,9 @@
35
35
  },
36
36
 
37
37
  getTitle: function(){
38
+ if (this.parent.kind === "extension"){
39
+ return "%s.%s".sprintf(this.parent.extends, this.name);
40
+ }
38
41
  var title = "%s.%s".sprintf(this.parent.name, this.name);
39
42
  if (this.parent.parent && this.parent.parent.kind == 'class' || this.parent.parent.kind == 'protocol'){
40
43
  title = "%s.%s".sprintf(this.parent.parent.name, title);
@@ -57,7 +60,7 @@
57
60
  elements.splice(index++, 0, params);
58
61
  params.setAttribute("class", "parameters");
59
62
  let header = params.appendChild(document.createElement("header"));
60
- let h1 = header.appendChild(document.createElement("h1"));
63
+ let h1 = header.appendChild(document.createElement("h2"));
61
64
  h1.setAttribute("outline-level", "1");
62
65
  h1.appendChild(document.createTextNode("Parameters"));
63
66
  let dl = fn.argumentListElement(document, this);
@@ -69,7 +72,7 @@
69
72
  elements.splice(index++, 0, returnSection);
70
73
  returnSection.setAttribute("class", "return");
71
74
  let header = returnSection.appendChild(document.createElement("header"));
72
- let h1 = header.appendChild(document.createElement("h1"));
75
+ let h1 = header.appendChild(document.createElement("h2"));
73
76
  h1.setAttribute("outline-level", "1");
74
77
  h1.appendChild(document.createTextNode("Return Value"));
75
78
 
@@ -0,0 +1,130 @@
1
+ // Copyright 2020 Breakside Inc.
2
+ //
3
+ // Licensed under the Breakside Public License, Version 1.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // If a copy of the License was not distributed with this file, you may
6
+ // obtain a copy at
7
+ //
8
+ // http://breakside.io/licenses/LICENSE-1.0.txt
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software
11
+ // distributed under the License is distributed on an "AS IS" BASIS,
12
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ // See the License for the specific language governing permissions and
14
+ // limitations under the License.
15
+
16
+ // #import "DocTopicBasedComponent.js"
17
+ 'use strict';
18
+
19
+ JSClass("DocExtension", DocTopicBasedComponent, {
20
+
21
+ kind: 'extension',
22
+ defaultChildKind: 'property',
23
+
24
+ // --------------------------------------------------------------------
25
+ // MARK: - Creating and populating
26
+
27
+ extractPropertiesFromInfo: async function(info, documentation){
28
+ await DocExtension.$super.extractPropertiesFromInfo.call(this, info, documentation);
29
+ let i = this.name.indexOf("+");
30
+ if (i < 0){
31
+ i = this.name.indexOf("(");
32
+ if (i < 0){
33
+ throw new Error("Extension %s name must include a +".sprintf(this.name));
34
+ }
35
+ }
36
+ if (this.name[i] === "("){
37
+ this.extends = info.extends || this.name.substr(0, i).trim();
38
+ i += 1;
39
+ this.extensionName = this.name.substr(i, this.name.length - 1 - i);
40
+ }else{
41
+ this.extends = info.extends || this.name.substr(0, i);
42
+ this.extensionName = this.name.substr(i + 1);
43
+ }
44
+ },
45
+
46
+ populateRelationships: function(){
47
+ DocExtension.$super.populateRelationships.call(this);
48
+ var parts = this.extends.split('.');
49
+ this.extendsComponent = this.componentForName(parts.shift());
50
+ while (parts.length > 0 && this.extendsComponent !== null){
51
+ this.extendsComponent = this.extendsComponent.childForName(parts.shift());
52
+ }
53
+ if (this.extendsComponent !== null){
54
+ if (this.extendsComponent.kind === "class"){
55
+ this.extendsComponent.addExtension(this);
56
+ }else if (this.extendsComponent.kind === "enum"){
57
+ this.extendsComponent.addExtension(this);
58
+ }
59
+ }
60
+ },
61
+
62
+ extends: null,
63
+ extensionName: null,
64
+ extendsComponent: null,
65
+
66
+ // --------------------------------------------------------------------
67
+ // MARK: - Naming
68
+
69
+ getDisplayNameForKind: function(){
70
+ return 'Extension';
71
+ },
72
+
73
+ // --------------------------------------------------------------------
74
+ // MARK: - Generating HTML
75
+
76
+ htmlArticleElements: function(document){
77
+ var elements = DocExtension.$super.htmlArticleElements.call(this, document);
78
+ var declaration = this.codeSectionElement(document, "Declaration", this.declarationCode(document));
79
+ declaration.setAttribute("class", "declaration");
80
+ elements.splice(1, 0, declaration);
81
+
82
+ let extension = document.createElement('section');
83
+ elements.push(extension);
84
+ extension.setAttribute("class", "extension");
85
+ let header = extension.appendChild(document.createElement("header"));
86
+ let h1 = header.appendChild(document.createElement("h2"));
87
+ h1.setAttribute("outline-level", "1");
88
+ h1.appendChild(document.createTextNode("Adds To"));
89
+ let p = extension.appendChild(document.createElement("p"));
90
+ let code = p.appendChild(document.createElement("code"));
91
+ let url = this.urlForCode(this.extends);
92
+ if (url !== null){
93
+ let a = code.appendChild(document.createElement("a"));
94
+ a.setAttribute("href", url.encodedString);
95
+ if (url.isAbsolute){
96
+ a.setAttribute("target", "_blank");
97
+ a.setAttribute("rel", "noopener noreferrer");
98
+ }
99
+ a.appendChild(document.createTextNode(this.extends));
100
+ }else{
101
+ code.appendChild(document.createTextNode(this.extends));
102
+ }
103
+
104
+ return elements;
105
+ },
106
+
107
+ declarationCode: function(document){
108
+ var tokens = [];
109
+ if (this.extendsComponent !== null){
110
+ if (this.extendsComponent.kind === "enum"){
111
+ tokens.push({value: this.extends, link: true});
112
+ tokens.push({value: "+= { ... }"});
113
+ }else if (this.extendsComponent.kind === "class"){
114
+ if (this.extendsComponent.inherits){
115
+ tokens.push({value: this.extends, link: true});
116
+ tokens.push({value: ".definePropertiesFromExtensions({ ... })"});
117
+ }else{
118
+ }
119
+ }
120
+ }
121
+ if (tokens.length === 0){
122
+ tokens.push({value: this.extends, link: true});
123
+ tokens.push({value: "+= { ... }"});
124
+ }
125
+ var lines = [];
126
+ lines.push(this.codeLineFromTokens(document, tokens));
127
+ return lines;
128
+ },
129
+
130
+ });
@@ -66,7 +66,7 @@
66
66
  elements.splice(index++, 0, params);
67
67
  params.setAttribute("class", "parameters");
68
68
  let header = params.appendChild(document.createElement("header"));
69
- let h1 = header.appendChild(document.createElement("h1"));
69
+ let h1 = header.appendChild(document.createElement("h2"));
70
70
  h1.setAttribute("outline-level", "1");
71
71
  h1.appendChild(document.createTextNode("Parameters"));
72
72
  let dl = this.argumentListElement(document, this);
@@ -78,7 +78,7 @@
78
78
  elements.splice(index++, 0, returnSection);
79
79
  returnSection.setAttribute("class", "return");
80
80
  let header = returnSection.appendChild(document.createElement("header"));
81
- let h1 = header.appendChild(document.createElement("h1"));
81
+ let h1 = header.appendChild(document.createElement("h2"));
82
82
  h1.setAttribute("outline-level", "1");
83
83
  h1.appendChild(document.createTextNode("Return Value"));
84
84
  if (this.valueType){
@@ -88,6 +88,10 @@
88
88
  if (url){
89
89
  let a = code.appendChild(document.createElement("a"));
90
90
  a.setAttribute("href", url.encodedString);
91
+ if (url.isAbsolute){
92
+ a.setAttribute("target", "_blank");
93
+ a.setAttribute("rel", "noopener noreferrer");
94
+ }
91
95
  a.appendChild(document.createTextNode(this.valueType));
92
96
  }else{
93
97
  code.appendChild(document.createTextNode(this.valueType));
@@ -149,6 +153,10 @@
149
153
  if (url !== null){
150
154
  let a = code.appendChild(document.createElement("a"));
151
155
  a.setAttribute("href", url.encodedString);
156
+ if (url.isAbsolute){
157
+ a.setAttribute("target", "_blank");
158
+ a.setAttribute("rel", "noopener noreferrer");
159
+ }
152
160
  a.appendChild(document.createTextNode(arg.type));
153
161
  }else{
154
162
  code.appendChild(document.createTextNode(arg.type));
@@ -37,6 +37,9 @@
37
37
 
38
38
  getTitle: function(){
39
39
  if (this.isStatic){
40
+ if (this.parent.kind == "extension"){
41
+ return "%s.%s".sprintf(this.parent.extends, this.name);
42
+ }
40
43
  return "%s.%s".sprintf(this.parent.name, this.name);
41
44
  }
42
45
  return this.name;
@@ -45,6 +45,9 @@
45
45
 
46
46
  getTitle: function(){
47
47
  if (this.isStatic){
48
+ if (this.parent.kind === "extension"){
49
+ return "%s.%s".sprintf(this.parent.extends, this.name);
50
+ }
48
51
  return "%s.%s".sprintf(this.parent.name, this.name);
49
52
  }
50
53
  return this.name;
@@ -62,7 +65,7 @@
62
65
  elements.splice(index++, 0, typeSection);
63
66
  typeSection.setAttribute("class", "return");
64
67
  let header = typeSection.appendChild(document.createElement("header"));
65
- let h1 = header.appendChild(document.createElement("h1"));
68
+ let h1 = header.appendChild(document.createElement("h2"));
66
69
  h1.appendChild(document.createTextNode("Value Type"));
67
70
  let p = typeSection.appendChild(document.createElement("p"));
68
71
  let code = p.appendChild(document.createElement("code"));
@@ -70,6 +73,10 @@
70
73
  if (url){
71
74
  let a = code.appendChild(document.createElement("a"));
72
75
  a.setAttribute("href", url.encodedString);
76
+ if (url.isAbsolute){
77
+ a.setAttribute("target", "_blank");
78
+ a.setAttribute("rel", "noopener noreferrer");
79
+ }
73
80
  a.appendChild(document.createTextNode(this.valueType));
74
81
  }else{
75
82
  code.appendChild(document.createTextNode(this.valueType));
@@ -85,7 +92,7 @@
85
92
  section.setAttribute("class", "variations");
86
93
  elements.push(section);
87
94
  let header = section.appendChild(document.createElement("header"));
88
- let h1 = header.appendChild(document.createElement("h1"));
95
+ let h1 = header.appendChild(document.createElement("h2"));
89
96
  h1.appendChild(document.createTextNode("Alternate Forms"));
90
97
 
91
98
  let ul = section.appendChild(document.createElement("ul"));
@@ -97,6 +104,10 @@
97
104
  li.setAttribute("class", variation.kind);
98
105
  let a = document.createElement("a");
99
106
  a.setAttribute("href", url.encodedString);
107
+ if (url.isAbsolute){
108
+ a.setAttribute("target", "_blank");
109
+ a.setAttribute("rel", "noopener noreferrer");
110
+ }
100
111
  let code = li.appendChild(document.createElement('code'));
101
112
  code.appendChild(a);
102
113
  a.appendChild(document.createTextNode(variation.name));
@@ -54,7 +54,7 @@
54
54
  elements.push(inherits);
55
55
  inherits.setAttribute("class", "inherits");
56
56
  let header = inherits.appendChild(document.createElement("header"));
57
- let h1 = header.appendChild(document.createElement("h1"));
57
+ let h1 = header.appendChild(document.createElement("h2"));
58
58
  h1.appendChild(document.createTextNode("Inherits From"));
59
59
  let p = inherits.appendChild(document.createElement("p"));
60
60
  let code = p.appendChild(document.createElement("code"));
@@ -62,6 +62,10 @@
62
62
  if (url !== null){
63
63
  let a = code.appendChild(document.createElement("a"));
64
64
  a.setAttribute("href", url.encodedString);
65
+ if (url.isAbsolute){
66
+ a.setAttribute("target", "_blank");
67
+ a.setAttribute("rel", "noopener noreferrer");
68
+ }
65
69
  a.appendChild(document.createTextNode(this.inherits));
66
70
  }else{
67
71
  code.appendChild(document.createTextNode(this.inherits));
@@ -57,12 +57,16 @@
57
57
  elements.push(inherits);
58
58
  inherits.setAttribute("class", "inherits");
59
59
  let header = inherits.appendChild(document.createElement("header"));
60
- let h1 = header.appendChild(document.createElement("h1"));
60
+ let h1 = header.appendChild(document.createElement("h2"));
61
61
  h1.appendChild(document.createTextNode("Inherits From"));
62
62
  let p = inherits.appendChild(document.createElement("p"));
63
63
  let code = p.appendChild(document.createElement("code"));
64
64
  let a = code.appendChild(document.createElement("a"));
65
65
  a.setAttribute("href", url.encodedString);
66
+ if (url.isAbsolute){
67
+ a.setAttribute("target", "_blank");
68
+ a.setAttribute("rel", "noopener noreferrer");
69
+ }
66
70
  a.appendChild(document.createTextNode(inheritedSpec.title));
67
71
  }
68
72
  }
@@ -42,7 +42,7 @@
42
42
  elements.splice(index++, 0, typeSection);
43
43
  typeSection.setAttribute("class", "return");
44
44
  let header = typeSection.appendChild(document.createElement("header"));
45
- let h1 = header.appendChild(document.createElement("h1"));
45
+ let h1 = header.appendChild(document.createElement("h2"));
46
46
  h1.appendChild(document.createTextNode("Resolved Value Type"));
47
47
  let p = typeSection.appendChild(document.createElement("p"));
48
48
  let code = p.appendChild(document.createElement("code"));
@@ -53,6 +53,10 @@
53
53
  if (url){
54
54
  let a = code.appendChild(document.createElement("a"));
55
55
  a.setAttribute("href", url.encodedString);
56
+ if (url.isAbsolute){
57
+ a.setAttribute("target", "_blank");
58
+ a.setAttribute("rel", "noopener noreferrer");
59
+ }
56
60
  a.appendChild(document.createTextNode(this.valueType));
57
61
  }else{
58
62
  code.appendChild(document.createTextNode(this.valueType));
@@ -65,7 +69,7 @@
65
69
  section.setAttribute("class", "variations");
66
70
  elements.push(section);
67
71
  let header = section.appendChild(document.createElement("header"));
68
- let h1 = header.appendChild(document.createElement("h1"));
72
+ let h1 = header.appendChild(document.createElement("h2"));
69
73
  h1.appendChild(document.createTextNode("Alternate Forms"));
70
74
 
71
75
  let ul = section.appendChild(document.createElement("ul"));
@@ -77,6 +81,10 @@
77
81
  li.setAttribute("class", variation.kind);
78
82
  let a = document.createElement("a");
79
83
  a.setAttribute("href", url.encodedString);
84
+ if (url.isAbsolute){
85
+ a.setAttribute("target", "_blank");
86
+ a.setAttribute("rel", "noopener noreferrer");
87
+ }
80
88
  let code = li.appendChild(document.createElement('code'));
81
89
  code.appendChild(a);
82
90
  a.appendChild(document.createTextNode(variation.name));
@@ -17,7 +17,7 @@
17
17
  /* global DocFunction */
18
18
  'use strict';
19
19
 
20
- JSClass("DocTopicBasedComponent", DocComponent, {
20
+ JSClass("DocTopicBasedComponent", DocComponent, {
21
21
 
22
22
  topics: null,
23
23
  defaultChildKind: null,
@@ -75,73 +75,83 @@
75
75
  htmlArticleElements: function(document){
76
76
  var elements = DocTopicBasedComponent.$super.htmlArticleElements.call(this, document);
77
77
  if (this.topics.length > 0){
78
- var topicsSection = document.createElement("section");
79
- elements.push(topicsSection);
80
- topicsSection.setAttribute("class", "topics");
81
- let header = topicsSection.appendChild(document.createElement("header"));
82
- let h1 = header.appendChild(document.createElement("h1"));
83
- h1.setAttribute("outline-level", "1");
84
- h1.appendChild(document.createTextNode("Topics"));
85
- for (let i = 0, l = this.topics.length; i < l; ++i){
86
- let topic = this.topics[i];
87
- if (topic.members.length === 0) continue;
88
- let section = topicsSection.appendChild(document.createElement("section"));
89
- section.setAttribute("class", "topic");
90
- let header = section.appendChild(document.createElement("header"));
91
- let h1 = header.appendChild(document.createElement("h1"));
92
- h1.appendChild(document.createTextNode(topic.name));
93
- h1.setAttribute("outline-level", "2");
94
- let div = section.appendChild(document.createElement('div'));
95
- if (topic.summary){
96
- let markdown = this.createMarkdownWithString(topic.summary);
97
- let children = markdown.htmlElementsForDocument(document);
98
- for (let j = 0, k = children.length; j < k; ++j){
99
- div.appendChild(children[j]);
100
- }
78
+ elements = elements.concat(this.htmlArticleTopicsElements(document, "Topics", this.topics));
79
+ }
80
+ return elements;
81
+ },
82
+
83
+ htmlArticleTopicsElements: function(document, title, topics){
84
+ let elements = [];
85
+ var topicsSection = document.createElement("section");
86
+ elements.push(topicsSection);
87
+ topicsSection.setAttribute("class", "topics");
88
+ let header = topicsSection.appendChild(document.createElement("header"));
89
+ let h1 = header.appendChild(document.createElement("h2"));
90
+ h1.setAttribute("outline-level", "1");
91
+ h1.appendChild(document.createTextNode(title));
92
+ for (let i = 0, l = topics.length; i < l; ++i){
93
+ let topic = topics[i];
94
+ if (topic.members.length === 0) continue;
95
+ let section = topicsSection.appendChild(document.createElement("section"));
96
+ section.setAttribute("class", "topic");
97
+ let header = section.appendChild(document.createElement("header"));
98
+ let h1 = header.appendChild(document.createElement("h3"));
99
+ h1.appendChild(document.createTextNode(topic.name));
100
+ h1.setAttribute("outline-level", "2");
101
+ let div = section.appendChild(document.createElement('div'));
102
+ if (topic.summary){
103
+ let markdown = this.createMarkdownWithString(topic.summary);
104
+ let children = markdown.htmlElementsForDocument(document);
105
+ for (let j = 0, k = children.length; j < k; ++j){
106
+ div.appendChild(children[j]);
101
107
  }
102
- let list = div.appendChild(document.createElement("ul"));
103
- list.setAttribute("class", "members");
104
- for (let j = 0, k = topic.members.length; j < k; ++j){
105
- let member = topic.members[j];
106
- let item = list.appendChild(document.createElement("li"));
107
- item.setAttribute("class", member.kind);
108
- let a = document.createElement("a");
109
- let url = this.urlForComponent(member);
110
- a.setAttribute("href", url.encodedString);
111
- if (member.kind == 'framework' || member.kind == 'document'){
112
- item.appendChild(a);
113
- }else{
114
- let code = item.appendChild(document.createElement('code'));
115
- let prefix = null;
116
- if (member.kind == 'method' || member.kind == 'property'){
117
- if (member.isStatic){
118
- prefix = 'static ';
119
- }
120
- }
121
- if (prefix === null){
122
- prefix = this.prefixForMember(member);
123
- }
124
- if (prefix !== null){
125
- code.appendChild(document.createTextNode(prefix));
126
- // let span = a.appendChild(document.createElement('span'));
127
- // span.setAttribute("class", "prefix");
128
- // span.appendChild(document.createTextNode(prefix + ' '));
129
- }
130
- code.appendChild(a);
131
- let suffix = this.suffixForMember(member);
132
- if (suffix !== null){
133
- code.appendChild(document.createTextNode(suffix));
108
+ }
109
+ let list = div.appendChild(document.createElement("ul"));
110
+ list.setAttribute("class", "members");
111
+ for (let j = 0, k = topic.members.length; j < k; ++j){
112
+ let member = topic.members[j];
113
+ let item = list.appendChild(document.createElement("li"));
114
+ item.setAttribute("class", member.kind);
115
+ let a = document.createElement("a");
116
+ let url = this.urlForComponent(member);
117
+ a.setAttribute("href", url.encodedString);
118
+ if (url.isAbsolute){
119
+ a.setAttribute("target", "_blank");
120
+ a.setAttribute("rel", "noopener noreferrer");
121
+ }
122
+ if (member.kind == 'framework' || member.kind == 'document'){
123
+ item.appendChild(a);
124
+ }else{
125
+ let code = item.appendChild(document.createElement('code'));
126
+ let prefix = null;
127
+ if (member.kind == 'method' || member.kind == 'property'){
128
+ if (member.isStatic){
129
+ prefix = 'static ';
134
130
  }
135
131
  }
136
- a.appendChild(document.createTextNode(this.nameForMember(member)));
137
- if (member.summary){
138
- let markdown = this.createMarkdownWithString(member.summary);
139
- let children = markdown.htmlElementsForDocument(document);
140
- for (let j = 0, k = children.length; j < k; ++j){
141
- item.appendChild(children[j]);
142
- }
143
-
132
+ if (prefix === null){
133
+ prefix = this.prefixForMember(member);
134
+ }
135
+ if (prefix !== null){
136
+ code.appendChild(document.createTextNode(prefix));
137
+ // let span = a.appendChild(document.createElement('span'));
138
+ // span.setAttribute("class", "prefix");
139
+ // span.appendChild(document.createTextNode(prefix + ' '));
144
140
  }
141
+ code.appendChild(a);
142
+ let suffix = this.suffixForMember(member);
143
+ if (suffix !== null){
144
+ code.appendChild(document.createTextNode(suffix));
145
+ }
146
+ }
147
+ a.appendChild(document.createTextNode(this.nameForMember(member)));
148
+ if (member.summary){
149
+ let markdown = this.createMarkdownWithString(member.summary);
150
+ let children = markdown.htmlElementsForDocument(document);
151
+ for (let j = 0, k = children.length; j < k; ++j){
152
+ item.appendChild(children[j]);
153
+ }
154
+
145
155
  }
146
156
  }
147
157
  }
@@ -172,4 +182,4 @@
172
182
  return obj;
173
183
  }
174
184
 
175
- });
185
+ });
@@ -20,6 +20,7 @@
20
20
  // #import "DocIndex.js"
21
21
  // #import "DocFramework.js"
22
22
  // #import "DocClass.js"
23
+ // #import "DocExtension.js"
23
24
  // #import "DocProtocol.js"
24
25
  // #import "DocMethod.js"
25
26
  // #import "DocInit.js"
@@ -44,6 +45,7 @@ JSClass("Documentation", JSObject, {
44
45
  this.fileManager = fileManager;
45
46
  },
46
47
 
48
+ customStylesheetURL: null,
47
49
  stylesheetURL: null,
48
50
  rootURL: null,
49
51
  outputDirectoryURL: null,
@@ -61,6 +63,7 @@ JSClass("Documentation", JSObject, {
61
63
  await this.copyStyles();
62
64
  let rootComponent = await this.loadSource(this.rootURL);
63
65
  rootComponent.outputURL = this.wwwURL.appendingPathComponent('index.html');
66
+ rootComponent.populateRelationships();
64
67
  await this.output([rootComponent]);
65
68
  await this.outputComponentsJSON(rootComponent);
66
69
  await this.outputManifestConfig(rootComponent);
@@ -197,17 +200,35 @@ JSClass("Documentation", JSObject, {
197
200
  var stylesURL = this.wwwURL.appendingPathComponent('_style', true);
198
201
  var metadata = JSBundle.mainBundle.metadataForResourceName('doc-default', 'css');
199
202
  var contents = await JSBundle.mainBundle.getResourceData(metadata);
200
- this.stylesheetURL = stylesURL.appendingPathComponent('default.css');
201
- await this.fileManager.createFileAtURL(this.stylesheetURL, contents);
203
+ var defaultStyleURL = stylesURL.appendingPathComponent('default.css');
204
+ await this.fileManager.createFileAtURL(defaultStyleURL, contents);
205
+ if (this.customStylesheetURL !== null){
206
+ var customStyleURL = stylesURL.appendingPathComponent(this.customStylesheetURL.lastPathComponent);
207
+ await this.fileManager.copyItemAtURL(this.customStylesheetURL, customStyleURL);
208
+ this.stylesheetURL = customStyleURL;
209
+ }else{
210
+ this.stylesheetURL = defaultStyleURL;
211
+ }
202
212
  },
203
213
 
204
214
  loadSource: async function(url){
205
- this.printer.setStatus("Reading %s...".sprintf(url.lastPathComponent));
206
- let exists = await this.fileManager.itemExistsAtURL(url);
207
- if (!exists){
215
+ if (url.scheme === "jskit"){
216
+ if (!this.hasAttemptedJSKitDownload){
217
+ await this.downloadJSKitDocumentation();
218
+ }
219
+ url = JSURL.initWithString(url.path + ".doc.yaml", this.jskitDocumenationLocalURL);
220
+ }
221
+ let contents = null;
222
+ if (url.scheme === JSFileManager.Scheme.file){
223
+ this.printer.setStatus("Reading %s...".sprintf(url.lastPathComponent));
224
+ let exists = await this.fileManager.itemExistsAtURL(url);
225
+ if (exists){
226
+ contents = await this.fileManager.contentsAtURL(url);
227
+ }
228
+ }
229
+ if (contents === null){
208
230
  return null;
209
231
  }
210
- let contents = await this.fileManager.contentsAtURL(url);
211
232
  let yaml = contents.stringByDecodingUTF8();
212
233
  let info = jsyaml.safeLoad(yaml);
213
234
  if (!info.name){
@@ -219,8 +240,64 @@ JSClass("Documentation", JSObject, {
219
240
  return component;
220
241
  },
221
242
 
243
+ jskitVersion: JSLazyInitProperty(() => JSBundle.mainBundle.info.JSBundleVersion),
244
+
245
+ jskitDocumenationRemoteURL: JSLazyInitProperty(function(){
246
+ let url = JSURL.initWithString("https://github.com/breakside/JSKit/archive/refs/tags/");
247
+ url.appendPathComponent("v" + this.jskitVersion + ".zip");
248
+ return url;
249
+ }),
250
+
251
+ jskitDocumenationLocalURL: JSLazyInitProperty(function(){
252
+ return JSURL.initWithString("JSKit", this.rootURL).appendingPathComponent(this.jskitVersion, true);
253
+ }),
254
+
255
+ hasAttemptedJSKitDownload: false,
256
+
257
+ downloadJSKitDocumentation: async function(){
258
+ if (!this.hasAttemptedJSKitDownload){
259
+ this.hasAttemptedJSKitDownload = true;
260
+ let exists = await this.fileManager.itemExistsAtURL(this.jskitDocumenationLocalURL);
261
+ if (!exists){
262
+ this.printer.setStatus("Downloading JSKit docs...");
263
+ let task = JSURLSession.shared.dataTaskWithURL(this.jskitDocumenationRemoteURL);
264
+ let response = await task.resume();
265
+ if (response.statusClass === JSURLResponse.StatusClass.success){
266
+ this.printer.setStatus("Unzipping JSKit docs...");
267
+ let zip = JSZip.initWithData(response.data);
268
+ if (zip !== null){
269
+ let docsPrefix = "JSKit-" + this.jskitVersion + "/Documentation/Code/";
270
+ let url;
271
+ let contents;
272
+ for (let filename of zip.filenames){
273
+ if (filename.startsWith(docsPrefix) && !filename.endsWith("/")){
274
+ contents = zip.dataForFilename(filename);
275
+ if (contents !== null){
276
+ filename = filename.substr(docsPrefix.length);
277
+ url = JSURL.initWithString(filename, this.jskitDocumenationLocalURL);
278
+ await this.fileManager.createFileAtURL(url, contents);
279
+ }else{
280
+ throw new Error("could not extract " + filename);
281
+ }
282
+ }
283
+ }
284
+ }else{
285
+ throw new Error("Could not read zip");
286
+ }
287
+ }else{
288
+ throw new Error("Response status is %d".sprintf(response.statusCode));
289
+ }
290
+ }
291
+ }
292
+ },
293
+
222
294
  createComponentFromInfo: async function(info, baseURL, defaultKind){
223
295
  if (typeof(info) === 'string'){
296
+ if (info.startsWith("jskit:")){
297
+ let url = JSURL.initWithString(info);
298
+ let component = await this.loadSource(url);
299
+ return component;
300
+ }
224
301
  let url = JSURL.initWithString(info + '.doc.yaml', baseURL);
225
302
  url.standardize();
226
303
  let component = await this.loadSource(url);
@@ -1197,7 +1197,9 @@ JSClass("HTMLBuilder", Builder, {
1197
1197
  this.httpServer.tlsKeyFileURL = JSURL.initWithString(this.arguments['tls-key'], this.workingDirectoryURL);
1198
1198
  }
1199
1199
  }
1200
- this.httpServer.run();
1200
+ await this.httpServer.run();
1201
+ }else{
1202
+ await this.httpServer.reload();
1201
1203
  }
1202
1204
  }else{
1203
1205
  if (this.httpServer !== null){