[CSS Grid Layout] LayoutBox::hasDefiniteLogicalHeight() should consider abspos boxes...
[WebKit-https.git] / Websites / webkit.org / status.html
1 <?php
2 $title = "Web Platform Status";
3 $extra_head_content = <<<EOF
4 <script>
5 function xhrPromise(url) {
6     return new Promise(function(resolve, reject) {
7         var xhrRequest = new XMLHttpRequest();
8         xhrRequest.open('GET', url, true);
9         xhrRequest.responseType = "json";
10
11         xhrRequest.onload = function() {
12             if (xhrRequest.status == 200) {
13                 if (xhrRequest.response) {
14                     resolve(xhrRequest.response);
15                 } else {
16                     reject({ request: xhrRequest, url:url});
17                 }
18             } else {
19                 reject({ request: xhrRequest, url:url});
20             }
21         };
22         xhrRequest.onerror = function() {
23             reject({ request: xhrRequest, url:url});
24         };
25         xhrRequest.send();
26     });
27 }
28 var origin = new URL("https://svn.webkit.org/")
29 var loadJavaScriptCoreFeatures = xhrPromise(new URL("/repository/webkit/trunk/Source/JavaScriptCore/features.json", origin));
30 var loadWebCoreFeatures = xhrPromise(new URL("/repository/webkit/trunk/Source/WebCore/features.json", origin));
31 </script>
32 EOF;
33 include("header.inc");
34 ?>
35 <style>
36 #feature-list {
37     margin-top: 2em;
38     word-wrap: break-word;
39     -webkit-text-size-adjust:135%;
40 }
41 #search {
42     width: 50%;
43     margin-top: 1em;
44     margin-bottom: 1em;
45 }
46 /* Hide the internal links on search since they are unlikely to work. */
47 #search:required:valid + *  .internal-reference {
48     display: none;
49 }
50
51 .feature-header {
52     display: -webkit-flex;
53     display: flex;
54     -webkit-flex-direction: row;
55     flex-direction: row;
56 }
57 .feature-header > h3:first-of-type {
58     -webkit-flex-grow: 1;
59     flex-grow: 1;
60     margin: 0;
61     font-size: 16px;
62     line-height: 1.4em;
63     text-shadow: none;
64 }
65 ul.features {
66     padding: 0;
67 }
68 .feature {
69     display: block;
70     background: linear-gradient(#fff, #f9f9f9);
71     border: 1px solid #bbb;
72     border-radius: 5px;
73     padding: 1em;
74     margin: 1em 0 !important;
75 }
76
77 .feature.is-hidden {
78     display: none;
79 }
80 .feature-desc {
81     margin: 0.4em 0;
82 }
83 ul.feature-details {
84     margin: 0;
85 }
86 .feature-statusItem {
87     margin-right: .5em;
88 }
89 </style>
90
91 <h2>WebKit Web Platform Status</h2>
92 <div id="feature-list">
93 </div>
94
95 <template id="success-template">
96     <input type="search" id="search" placeholder="Filter" title="Filter the feature list." required>
97     <ul class="features" id="features-container"></ul>
98     <p>Cannot find something? You can contact <a href="https://twitter.com/webkit">@webkit</a> on Twitter or contact the <a href="https://lists.webkit.org/mailman/listinfo/webkit-help">webkit-help</a> mailing list for questions.</p>
99     <p>You can also <a href="http://127.0.0.1:8000/coding/contributing.html">contribute to features</a> directly, the entire project is Open Source. To report bugs on existing features or check existing bug reports, see <a href="https://bugs.webkit.org">https://bugs.webkit.org</a>.</p>
100 </template>
101 <template id="error-template">
102     <p>Error: unable to load the features list (<span id="error-message"></span>).</p>
103     <p>If this is not resolved soon, please contact <a href="https://twitter.com/webkit">@webkit</a> on Twitter or the <a href="https://lists.webkit.org/mailman/listinfo/webkit-help">webkit-help</a> mailing list.</p>
104 </template>
105
106 <script>
107 function initializeStatusPage() {
108     function sortAlphabetically(array) {
109         array.sort(function(a, b){
110             var aName = a.name.toLocaleLowerCase();
111             var bName = b.name.toLocaleLowerCase();
112             
113             if (aName < bName) {
114                 return -1;
115             }
116             if (aName > bName) {
117                 return 1;
118             }
119             return 0;
120         });
121     }
122
123     function createFeatureView(featureObject) {
124         function createLinkWithHeading(elementName, heading, linkText, linkUrl) {
125             var container = document.createElement(elementName);
126             if (heading) {
127                 container.textContent = heading + ": ";
128             }
129             var link = document.createElement("a");
130             link.textContent = linkText;
131             link.href = linkUrl;
132             container.appendChild(link);
133             return container;
134         }
135
136         var container = document.createElement('li');
137         container.className = "feature";
138
139         if ("features" in featureObject) {
140             container.setAttribute("id", "specification-" + featureObject.name);
141         } else {
142             container.setAttribute("id", "feature-" + featureObject.name);
143         }
144
145         var descriptionContainer = document.createElement('div');
146         descriptionContainer.className = "feature-description";
147
148         var featureHeaderContainer = document.createElement('div');
149         featureHeaderContainer.className = "feature-header";
150         descriptionContainer.appendChild(featureHeaderContainer);
151
152         var titleElement = document.createElement("h3");
153         titleElement.textContent = featureObject.name;
154         featureHeaderContainer.appendChild(titleElement);
155
156         if ("status" in featureObject) {
157             var statusContainer = document.createElement("span");
158             statusContainer.className = "feature-status";
159             if ("webkit-url" in featureObject) {
160                 statusContainer.textContent = "Status: ";
161                 var statusLink = document.createElement("a");
162                 statusLink.href = featureObject["webkit-url"];
163                 statusLink.textContent = featureObject.status.status;
164                 statusContainer.appendChild(statusLink);
165             } else {
166                 statusContainer.textContent = "Status: " + featureObject.status.status;
167             }
168
169             featureHeaderContainer.appendChild(statusContainer);
170         }
171
172         if ("description" in featureObject) {
173             var testDescription = document.createElement('p');
174             testDescription.className = "feature-desc";
175             testDescription.innerHTML = featureObject.description;
176             descriptionContainer.appendChild(testDescription);
177         }
178
179         if ("comment" in featureObject) {
180             if ("description" in featureObject) {
181                 descriptionContainer.appendChild(document.createElement("hr"));
182             }
183             var comment = document.createElement('p');
184             comment.innerHTML = featureObject.comment;
185             descriptionContainer.appendChild(comment);
186         }
187
188         container.appendChild(descriptionContainer);
189
190         var hasDocumentationLink = "documentation-url" in featureObject;
191         var hasReferenceLink = "url" in featureObject;
192         var hasContactObject = "contact" in featureObject;
193         var hasSpecificationObject = "specification" in featureObject;
194         if (hasDocumentationLink || hasReferenceLink || hasContactObject) {
195             var moreInfoList = document.createElement("ul");
196             if (hasDocumentationLink) {
197                 var url = featureObject["documentation-url"];
198                 moreInfoList.appendChild(createLinkWithHeading("li", "Documentation", url, url));
199             }
200
201             if (hasReferenceLink) {
202                 var url = featureObject.url;
203                 moreInfoList.appendChild(createLinkWithHeading("li", "Reference", url, url));
204             }
205
206             if (hasSpecificationObject) {
207                 var specification = featureObject.specification;
208                 var li = createLinkWithHeading("li", "Parent feature", specification.name, ("#specification-" + specification.name));
209                 li.className = "internal-reference";
210                 moreInfoList.appendChild(li);
211             }
212
213             if (hasContactObject) {
214                 var li = document.createElement("li");
215                 li.textContent = "Contact: ";
216                 if (featureObject.contact.twitter) {
217                     li.appendChild(createLinkWithHeading("span", null, featureObject.contact.twitter, featureObject.contact.twitter));
218                 }
219                 if (featureObject.contact.email) {
220                     if (featureObject.contact.twitter) {
221                         li.appendChild(document.createTextNode(" - "));
222                     }
223                     var emailText = featureObject.contact.email;
224                     if (featureObject.contact.name) {
225                         emailText = featureObject.contact.name;
226                     }
227                     li.appendChild(createLinkWithHeading("span", null, emailText, featureObject.contact.email));
228                 }
229                 moreInfoList.appendChild(li);
230             }
231
232             container.appendChild(moreInfoList);
233         }
234
235         if ("features" in featureObject && featureObject.features.length) {
236             var internalLinkContainer = document.createElement("div");
237             internalLinkContainer.className = "internal-reference";
238             var trackedFeatures = document.createElement("p");
239             trackedFeatures.textContent = "Subfeatures: ";
240             internalLinkContainer.appendChild(trackedFeatures);
241
242             var list = document.createElement("ul");
243             for (var feature of featureObject.features) {
244                 var link = document.createElement("a");
245                 link.textContent = feature.name;
246                 link.href = "#feature-" + feature.name;
247
248                 var li = document.createElement("li");
249                 li.appendChild(link);
250                 list.appendChild(li);
251             }
252             internalLinkContainer.appendChild(list);
253             container.appendChild(internalLinkContainer);
254         }
255
256         return container;
257     }
258
259     function renderFeaturesAndSpecifications(featureLikeObjects) {
260         var featureContainer = document.getElementById('features-container');
261         for (var featureLikeObject of featureLikeObjects) {
262             featureContainer.appendChild(createFeatureView(featureLikeObject));
263         }
264     }
265
266     function initSearch(featuresArray) {
267         var inputField = document.getElementById('search');
268         var featuresEls = document.querySelectorAll('.features > li');
269         
270         featuresArray.forEach(function(feature, i) {
271             feature.el = featuresEls[i];
272             feature.visible = true;
273         });
274
275         inputField.addEventListener('input', search);
276
277         function search(ev) {
278             var searchTerm = inputField.value.trim().toLowerCase();
279             searchFeatures(featuresArray, searchTerm);
280         }
281     }
282
283     function searchFeatures(featuresArray, searchTerm) {
284         featuresArray.forEach(function(feature) {
285             var visible = isSearchMatch(feature, searchTerm);
286             
287             if (visible && !feature.visible) {
288                 feature.el.className = 'feature';
289             } else if (!visible && feature.visible) {
290                 feature.el.className = 'feature is-hidden';
291             }
292             
293             feature.visible = visible;
294         });
295     }
296
297     function isSearchMatch(feature, searchTerm) {
298         if (feature.name.toLowerCase().indexOf(searchTerm) !== -1)
299             return true;
300         if ("keywords" in feature) {
301             for (var keyword of feature.keywords) {
302                 if (keyword.toLowerCase().indexOf(searchTerm) !== -1)
303                     return true;
304             }
305         }
306         return false;
307     }
308
309     function displayFeatures(results)
310     {
311         var mainContent = document.getElementById("feature-list");
312         var successSubtree = document.importNode(document.getElementById("success-template").content, true);
313         mainContent.appendChild(successSubtree);
314
315         var allSpecifications = [];
316         for (var i in results) {
317             allSpecifications = allSpecifications.concat(results[i].specification);
318         }
319         var specificationsByName = {}
320         for (var specification of allSpecifications) {
321             specification.features = [];
322             specification.isSpecification = true;
323             specificationsByName[specification.name] = specification;
324         }
325
326         var allFeatures = [];
327         for (var i in results) {
328             allFeatures = allFeatures.concat(results[i].features);
329         }
330         var featuresByName = {};
331         for (var feature of allFeatures) {
332             if ('specification' in feature) {
333                 var specificationObject = specificationsByName[feature.specification];
334                 specificationObject.features.push(feature);
335                 feature.specification = specificationObject;
336             }
337             feature.isSpecification = false;
338             featuresByName[feature.name] = feature;
339         }
340
341         var everythingToShow = allFeatures.concat(allSpecifications);
342         sortAlphabetically(everythingToShow);
343         renderFeaturesAndSpecifications(everythingToShow);
344         initSearch(everythingToShow);
345     }
346
347     function displayError(error)
348     {
349         var mainContent = document.getElementById("feature-list");
350         var successSubtree = document.importNode(document.getElementById("error-template").content, true);
351
352         var errorMessage = "Unable to load " + error.url;
353
354         if (error.request.status !== 200) {
355             errorMessage += ", status: " + error.request.status + " - " + error.request.statusText;
356         } else if (!error.response) {
357             errorMessage += ", the JSON file cannot be processed.";
358         }
359
360         successSubtree.querySelector("#error-message").textContent = errorMessage;
361
362         mainContent.appendChild(successSubtree);
363     }
364
365     Promise.all([loadJavaScriptCoreFeatures, loadWebCoreFeatures]).then(displayFeatures).catch(displayError);
366 }
367
368 document.addEventListener("DOMContentLoaded", initializeStatusPage);
369 </script>
370
371 <?php include("footer.inc"); ?>