| <?php |
| /** |
| * Template Name: CSS Status Page |
| **/ |
| ?> |
| <?php get_header(); ?> |
| <script> |
| function xhrPromise(url) { |
| return new Promise(function(resolve, reject) { |
| var xhrRequest = new XMLHttpRequest(); |
| xhrRequest.open('GET', url, true); |
| xhrRequest.responseType = "json"; |
| |
| xhrRequest.onload = function() { |
| if (xhrRequest.status == 200 || xhrRequest.status == 0) { |
| if (xhrRequest.response) { |
| resolve(xhrRequest.response); |
| } else { |
| reject({ request: xhrRequest, url:url}); |
| } |
| } else { |
| reject({ request: xhrRequest, url:url}); |
| } |
| }; |
| xhrRequest.onerror = function() { |
| reject({ request: xhrRequest, url:url}); |
| }; |
| xhrRequest.send(); |
| }); |
| } |
| |
| var origin = new URL("https://<?php echo strpos(WP_HOST, "webkit.org") !== false ? "svn.webkit.org" : WP_HOST; ?>/"); |
| var loadCSSProperties = xhrPromise(new URL("/repository/webkit/trunk/Source/WebCore/css/CSSProperties.json", origin)); |
| |
| </script> |
| |
| <style> |
| :root { |
| --feature-rule-color: hsl(0, 0%, 89.4%); |
| --status-color: hsl(0, 0%, 60%); |
| --supported-color: hsl(100, 100%, 30%); |
| --non-standard-color: hsl(275.4, 77.7%, 35.1%); |
| --in-development-color: hsl(24.5, 91.3%, 50.6%); |
| --no-active-development-color: hsl(240, 60.6%, 59.2%); |
| --partially-supported-color: hsl(180, 25%, 43.9%); |
| --experimental-color: hsl(211.3, 100%, 50%); |
| --under-consideration-color: hsl(5.9, 40.2%, 60%); |
| --removed-not-considering-color: hsl(0, 0%, 49.8%); |
| --not-implemented-color: hsl(0, 0%, 29.8%); |
| --obsolete-color: hsl(50, 100%, 25.1%); |
| } |
| |
| @media(prefers-color-scheme:dark) { |
| :root { |
| --feature-rule-color: hsl(0, 0%, 20%); |
| --status-color: hsl(0, 0%, 51%); |
| --supported-color: hsl(79.5, 45.3%, 52%); |
| --non-standard-color: hsl(276.7, 36.3%, 51.4%); |
| --in-development-color: hsl(24.5, 91.3%, 50.6%); |
| --no-active-development-color: hsl(240, 60.6%, 59.2%); |
| --partially-supported-color: hsl(180, 30%, 52%); |
| --exoerimental-color: hsl(211.3, 100%, 50%); |
| --under-consideration-color: hsl(0, 35%, 61%); |
| --removed-not-considering-color: hsl(0, 0%, 49.8%); |
| --not-implemented-color: hsl(0, 0%, 70.2%); |
| --obsolete-color: hsl(31.9, 20.5%, 33.1%); |
| } |
| } |
| |
| .feature-status-page { |
| animation: none !important; /* This animation can trigger a hit-testing bug, so remove it for now */ |
| } |
| |
| .page { |
| display: -webkit-flex; |
| display: flex; |
| flex-direction: column; |
| -webkit-justify-content: space-between; |
| justify-content: space-between; |
| box-sizing: border-box; |
| width: 100%; |
| } |
| |
| .page h1 { |
| font-size: 4.2rem; |
| font-weight: 500; |
| line-height: 6rem; |
| margin: 3rem auto; |
| width: 100%; |
| text-align: center; |
| } |
| |
| .page h1 a { |
| color: inherit; |
| } |
| |
| .page h2 { |
| font-weight: 200; |
| font-size: 3rem; |
| } |
| |
| .page h3 { |
| font-weight: 400; |
| font-size: 2.2rem; |
| } |
| |
| .css-feature-page { |
| padding-bottom: 3rem; |
| } |
| |
| .css-feature-page p { |
| max-width: 920px; |
| margin: 0 auto 3rem; |
| } |
| |
| /* Feature Filters */ |
| .feature-filters { |
| background-color: hsl(0, 0%, 0%); |
| background-color: var(--figure-mattewhite-background-color); |
| width: 100vw; |
| left: 50%; |
| position: relative; |
| transform: translate(-50vw, 0); |
| box-sizing: border-box; |
| margin-bottom: 3rem; |
| border: 1px solid hsl(0, 0%, 90.6%); |
| border-color: var(--article-border-color); |
| border-left: none; |
| border-right: none; |
| } |
| |
| .feature-filters .search-input { |
| background-repeat: no-repeat; |
| background-position-x: 0.5rem; |
| background-position-y: 1rem; |
| background-size: 2rem; |
| padding: 1rem; |
| padding-left: 3rem; |
| padding-right: 8.5rem; |
| font-size: 2rem; |
| width: 100%; |
| margin-top: 0rem; |
| margin-bottom: 0rem; |
| box-sizing: border-box; |
| border-color: transparent; |
| } |
| |
| .feature-filters li { |
| display: inline-block; |
| white-space: no-wrap; |
| } |
| |
| .property-status label, |
| .feature-filters label { |
| display: table-cell; |
| padding: 0.5rem 1rem; |
| border-style: solid; |
| border-width: 1px; |
| border-radius: 3px; |
| cursor: pointer; |
| float: right; |
| line-height: 1; |
| font-size: 1.6rem; |
| } |
| |
| #status-filters { |
| display: none; |
| text-align: center; |
| margin-top: 1rem; |
| margin-bottom: 0; |
| } |
| |
| .property-filters { |
| max-width: 920px; |
| margin: 0 auto 0; |
| position: relative; |
| top: 0; |
| } |
| |
| .property-filters.opened { |
| margin-top: 1.5rem; |
| } |
| |
| .property-filters.opened #status-filters { |
| display: block; |
| } |
| |
| #status-filters label { |
| margin-left: 1rem; |
| margin-bottom: 1rem; |
| float: none; |
| display: inline-block; |
| position: relative; |
| } |
| |
| .feature-filters label { |
| float: none; |
| display: inline-block; |
| } |
| |
| .status-filters { |
| list-style: none; |
| display: inline-block; |
| text-align: center; |
| } |
| |
| .filter-toggle:checked + .filter-status { |
| color: hsl(240, 1.3%, 84.5%); |
| color: var(--text-color); |
| } |
| |
| .filter-status, |
| .feature-status { |
| color: hsl(0, 0%, 60%); |
| color: var(--status-color); |
| border-color: hsl(0, 0%, 60%); |
| border-color: var(--status-color); |
| } |
| |
| .feature-status a { |
| color: inherit; |
| } |
| |
| .status-filter, |
| .status-marker { |
| border-color: hsl(0, 0%, 60%); |
| border-color: var(--status-color) |
| } |
| |
| .filter-toggle:checked + .filter-status { |
| background-color: hsl(0, 0%, 60%); |
| background-color: var(--status-color); |
| } |
| |
| .property-description.status-marker { |
| border-left-width: 3px; |
| border-left-style: solid; |
| padding: 0.5rem 0 0.5rem 1rem; |
| } |
| |
| .property-count { |
| max-width: 920px; |
| margin: 0 auto 3rem; |
| |
| text-align: right; |
| color: hsl(240, 2.3%, 56.7%); |
| color: var(--text-color-coolgray); |
| } |
| |
| .property-header > h3:first-of-type { |
| -webkit-flex-grow: 1; |
| flex-grow: 1; |
| margin: 0; |
| } |
| |
| .property-header:after { |
| position: relative; |
| width: 2rem; |
| height: 2rem; |
| right: 0; |
| top: 0.5rem; |
| margin-left: 1rem; |
| transition: transform 0.3s ease-out; |
| } |
| |
| .properties { |
| padding: 0; |
| max-width: 920px; |
| margin: 0 auto 3rem; |
| border-bottom: 1px solid hsl(0, 0%, 89.4%); |
| border-color: var(--feature-rule-color); |
| } |
| |
| .properties .property { |
| position: relative; |
| display: block; |
| max-height: intrinsic; |
| min-height: 3rem; |
| overflow-y: hidden; |
| cursor: pointer; |
| background-color: transparent; |
| border-color: transparent; |
| border-width: 1px; |
| border-style: solid; |
| border-top-color: hsl(0, 0%, 89.4%); |
| border-top-color: var(--feature-rule-color); |
| padding: 0.5rem; |
| line-height: 1.618; |
| transition: background-color 0.3s ease-in; |
| } |
| |
| .property.opened { |
| background-color: hsl(0, 0%, 100%); |
| background-color: var(--figure-mattewhite-background-color); |
| border-left-color: hsl(0, 0%, 89.4%); |
| border-left-color: var(--feature-rule-color); |
| border-right-color: hsl(0, 0%, 89.4%); |
| border-right-color: var(--feature-rule-color); |
| max-height: 120rem; |
| } |
| |
| .property.opened .property-header:after { |
| -webkit-transform: rotateX(-180deg); |
| -moz-transform: rotateX(-180deg); |
| transform: rotateX(-180deg); |
| perspective: 600; |
| } |
| |
| .property-description .toggleable { |
| display: none; |
| } |
| |
| .property.opened .property-description .toggleable { |
| display: block; |
| margin-top: 1rem; |
| } |
| |
| .comment { |
| font-size: smaller; |
| } |
| |
| .more-info { |
| margin-top: 0.5em; |
| font-size: smaller; |
| } |
| |
| .sub-features { |
| font-size: 1.5rem; |
| color: #555; |
| } |
| |
| .sub-features ul { |
| list-style: none; |
| display: inline-block; |
| padding: 0; |
| margin: 0; |
| } |
| |
| .sub-features li { |
| display: inline; |
| } |
| |
| .sub-features li:after { |
| content: ", "; |
| } |
| |
| .sub-features li:last-child:after { |
| content: ""; |
| } |
| |
| ul.values { |
| margin-left: 3em; |
| margin-bottom: 0.5em; |
| cursor: default; |
| } |
| |
| .values li.hidden { |
| color: #444; |
| } |
| |
| .property-header { |
| position: relative; |
| display: -webkit-flex; |
| display: flex; |
| -webkit-flex-direction: row; |
| flex-direction: row; |
| } |
| |
| .property-header .toggle { |
| display: inline-block; |
| background: url('images/menu-down.svg') no-repeat 50%; |
| background-size: 2rem; |
| border: none; |
| width: 2rem; |
| height: 2rem; |
| position: absolute; |
| right: 0; |
| top: 0.5rem; |
| transition: transform 0.3s ease-out; |
| } |
| |
| .property.opened .property-header .toggle { |
| transform: rotateX(-180deg); |
| } |
| |
| .property-header h3 .spec-label , |
| .property-header h3 .spec-label a { |
| text-decoration: none; |
| font-weight: 200; |
| color: hsl(0, 0%, 33.3%); |
| color: var(--text-color-medium); |
| } |
| |
| .spec-label::before { |
| content: ' — '; |
| } |
| |
| .property-description .toggleable { |
| color: hsl(0, 0%, 20%); |
| color: var(--text-color); |
| } |
| |
| .property-header h3, |
| .property-header a[name] { |
| color: hsl(0, 0%, 26.7%); |
| color: var(--text-color-heading); |
| } |
| |
| .property-alias { |
| font-size: smaller; |
| } |
| |
| .property-header p { |
| margin-top: 0.5rem; |
| margin-bottom: 0.5rem; |
| } |
| |
| .property-alias, |
| .value-alias, |
| .value-status { |
| color: hsl(240, 2.3%, 56.7%); |
| color: var(--text-color-coolgray); |
| } |
| |
| .property.is-hidden { |
| display: none; |
| } |
| |
| ul.property-details { |
| margin: 0; |
| } |
| .property-statusItem { |
| margin-right: 0.5em; |
| } |
| |
| |
| .property-status, |
| .property-status a { |
| color: #999; |
| } |
| |
| .property .status-marker { |
| border-left-width: 3px; |
| border-left-style: solid; |
| padding: 0.5rem 0 0.5rem 1rem; |
| } |
| |
| |
| .status-marker { |
| border-color: hsl(0, 0%, 60%); |
| border-color: var(--status-color) |
| } |
| |
| .supported { |
| color: hsl(100, 100%, 30%); |
| color: var(--supported-color); |
| border-color: hsl(100, 100%, 30%); |
| border-color: var(--supported-color); |
| } |
| |
| .in-development { |
| color: hsl(24.5, 91.3%, 50.6%); |
| color: var(--in-development-color); |
| border-color: hsl(24.5, 91.3%, 50.6%); |
| border-color: var(--in-development-color); |
| } |
| |
| .under-consideration { |
| color: hsl(5.9, 40.2%, 60%); |
| color: var(--under-consideration-color); |
| border-color: hsl(5.9, 40.2%, 60%); |
| border-color: var(--under-consideration-color); |
| } |
| |
| .no-active-development { |
| color: hsl(240, 60.6%, 59.2%); |
| color: var(--no-active-development-color); |
| border-color: hsl(240, 60.6%, 59.2%); |
| border-color: var(--no-active-development-color); |
| } |
| |
| .experimental { |
| color: hsl(211.3, 100%, 50%); |
| color: var(--experimental-color); |
| border-color: hsl(211.3, 100%, 50%); |
| border-color: var(--experimental-color); |
| } |
| |
| .partial-support { |
| color: hsl(180, 25%, 43.9%); |
| color: var(--partially-supported-color); |
| border-color: hsl(180, 25%, 43.9%); |
| border-color: var(--partially-supported-color); |
| } |
| |
| .non-standard { |
| color: hsl(275.4, 77.7%, 35.1%); |
| color: var(--non-standard-color); |
| border-color: hsl(275.4, 77.7%, 35.1%); |
| border-color: var(--non-standard-color); |
| } |
| |
| .removed, |
| .not-considering { |
| color: hsl(0, 0%, 49.8%); |
| color: var(--removed-not-considering-color); |
| border-color: hsl(0, 0%, 49.8%); |
| border-color: var(--removed-not-considering-color); |
| } |
| |
| .not-implemented { |
| color: hsl(0, 0%, 29.8%); |
| color: var(--not-implemented-color); |
| border-color: hsl(0, 0%, 29.8%); |
| border-color: var(--not-implemented-color); |
| } |
| |
| .obsolete { |
| color: hsl(50, 100%, 25.1%); |
| color: var(--obsolete-color); |
| border-color: hsl(50, 100%, 25.1%); |
| border-color: var(--obsolete-color); |
| } |
| |
| .by-specification { |
| background-color: hsl(0, 0%, 96.9%); |
| background-color: var(--content-background-color); |
| border-color: hsl(0, 0%, 83.9%); |
| border-color: var(--input-border-color); |
| } |
| |
| .property-filters.opened .search-input { |
| border-color: hsl(0, 0%, 83.9%); |
| border-color: var(--input-border-color); |
| } |
| |
| .feature-filters .filters-toggle-button { |
| background-repeat: no-repeat; |
| background-size: 2rem; |
| background-position: right; |
| background-filter: lightness(2); |
| position: absolute; |
| padding-right: 2.5rem; |
| right: 1rem; |
| top: 1rem; |
| border: none; |
| color: hsl(240, 2.3%, 56.7%); |
| } |
| |
| .feature-filters .filters-toggle-button:hover { |
| filter: brightness(0); |
| } |
| |
| #filters-toggle { |
| display: none; |
| } |
| |
| .property-filters ul { |
| margin-top: 0.5rem; |
| } |
| |
| .property-filters ul li { |
| margin-bottom: 0.5rem; |
| } |
| |
| .property-filters label > input { |
| position: relative; |
| top: -1px; |
| } |
| |
| .prefixes { |
| display: none; |
| } |
| |
| #specifications { |
| display: inline-block; |
| font-size: 1.6rem; |
| color: hsl(0, 0%, 20%); |
| color: var(--text-color); |
| margin-left: 1rem; |
| } |
| |
| .filter-by-specifications-toggle { |
| position: absolute; |
| display: none; |
| left: 1000rem; |
| top: 0; |
| width: 100%; |
| height: 100%; |
| } |
| |
| #specifications:disabled + .filter-by-specifications-toggle { |
| display: block; |
| top: 0; |
| left: 0; |
| } |
| |
| h3 a[name], .admin-bar h3 a[name] { |
| top: initial; |
| width: auto; |
| display: inline-block; |
| visibility: visible; /* Override visibility:hidden from themes/webkit/style.css */ |
| } |
| |
| .pagination:after { |
| display: none; |
| } |
| |
| .pagination, |
| .pagination + h1 { |
| margin-top: 0; |
| } |
| |
| @media only screen and (max-width: 1180px) { |
| .feature-filters .filters-toggle-button { |
| right: 3rem; |
| } |
| } |
| |
| @media only screen and (max-width: 508px) { |
| #property-filters, |
| #property-list { |
| width: 100%; |
| } |
| |
| #property-filters { |
| padding-left: 2rem; |
| padding-right: 2rem; |
| } |
| |
| .property-header h3 { |
| font-size: 2rem; |
| padding-right: 0.5rem; |
| } |
| |
| .property-status { |
| font-size: 1.6rem; |
| margin-top: 0.4rem; |
| float: left; |
| } |
| |
| .property-header:after { |
| width: 1rem; |
| height: 1rem; |
| background-size: 1rem; |
| top: 1rem; |
| } |
| |
| .property h3 { |
| font-size: 2rem; |
| padding-top: 4rem; |
| } |
| |
| .property-header .property-status { |
| font-size: 1.6rem; |
| position: absolute; |
| text-align: left; |
| } |
| |
| .property .moreinfo { |
| flex-wrap: wrap; |
| } |
| |
| .property .moreinfo .contact { |
| text-align: left; |
| } |
| |
| .status-filters { |
| flex-basis: 100%; |
| } |
| |
| .status-filters label { |
| margin-left: 0; |
| margin-right: 1rem; |
| } |
| } |
| |
| @media(prefers-color-scheme:dark) { |
| .property-header:after { |
| filter: invert(1); |
| } |
| |
| .search-input:hover, |
| .search-input:focus, |
| .feature-filters .filters-toggle-button:hover { |
| filter: brightness(2); |
| } |
| } |
| |
| </style> |
| <?php if (have_posts()) : while (have_posts()) : the_post(); ?> |
| |
| <div class="page css-feature-page" id="post-<?php the_ID(); ?>"> |
| |
| <div class="connected pagination"> |
| <?php wp_nav_menu( array('theme_location' => 'feature-subnav') ); ?> |
| </div> |
| |
| <h1><a href="<?php echo get_permalink() ?>" rel="bookmark" title="Permanent Link: <?php the_title(); ?>"><?php the_title(); ?></a></h1> |
| |
| <section class="feature-filters"> |
| <form id="property-filters" class="property-filters page-width"> |
| <input type="text" id="search" class="search-input" placeholder="Search CSS Features…" title="Filter the property list." required><label class="filters-toggle-button">Filters</label> |
| <ul id="status-filters"> |
| </ul> |
| |
| <div class="prefixes"> |
| <h2>Filter by Prefix</h2> |
| <ul id="prefix-filters"> |
| </ul> |
| </div> |
| |
| </form> |
| </section> |
| |
| <section class="primary"> |
| <div id="property-list"> |
| <div class="property-count"> |
| <p><span id="property-count"></span> <span id="property-pluralize">properties</span></p> |
| </div> |
| </div> |
| |
| <template id="success-template"> |
| <ul class="properties" id="properties-container"></ul> |
| |
| <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> |
| <p>You can also <a href="/contributing-code/">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> |
| </template> |
| |
| <template id="error-template"> |
| <p>Error: unable to load the features list (<span id="error-message"></span>).</p> |
| <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> |
| </template> |
| |
| </section> |
| </div> |
| |
| <?php //comments_template(); ?> |
| |
| <?php endwhile; else: ?> |
| |
| <p>No posts.</p> |
| |
| <?php endif; ?> |
| |
| |
| <script> |
| function initializeStatusPage() { |
| |
| const statusOrder = [ |
| 'supported', |
| 'in-development', |
| 'under-consideration', |
| 'experimental', |
| 'non-standard', |
| 'not-considering', |
| 'not-implemented', |
| 'obsolete', |
| 'removed', |
| ]; |
| |
| const readableStatus = { |
| 'supported': 'Supported', |
| 'in-development': 'In Development', |
| 'under-consideration': 'Under Consideration', |
| 'experimental': 'Experimental', |
| 'non-standard': 'Non-standard', |
| 'not-considering': 'Not considering', |
| 'not-implemented': 'Not implemented', |
| 'obsolete': 'Obsolete', |
| 'removed': 'Removed', |
| }; |
| |
| function sortAlphabetically(array) |
| { |
| function replaceDashPrefix(name) |
| { |
| if (name[0] == '-') |
| return 'Z' + name.slice(1); |
| return name; |
| } |
| |
| array.sort(function(a, b) { |
| // Sort the prefixed properties to the end. |
| var aName = replaceDashPrefix(a.name.toLowerCase()); |
| var bName = replaceDashPrefix(b.name.toLowerCase()); |
| |
| var nameCompareResult = aName.localeCompare(bName); |
| |
| if (nameCompareResult) |
| return nameCompareResult; |
| |
| // Status sort |
| var aStatus = a.status != undefined ? a.status.status.toLowerCase() : ''; |
| var bStatus = b.status != undefined ? b.status.status.toLowerCase() : ''; |
| |
| return aStatus.localeCompare(bStatus); |
| }); |
| } |
| |
| function propertyNameAliases(propertyObject) |
| { |
| if ('codegen-properties' in propertyObject && 'aliases' in propertyObject['codegen-properties']) |
| return propertyObject['codegen-properties'].aliases; |
| |
| return []; |
| } |
| |
| function propertyLonghands(propertyObject) |
| { |
| if ('codegen-properties' in propertyObject && 'longhands' in propertyObject['codegen-properties']) |
| return propertyObject['codegen-properties'].longhands; |
| |
| return []; |
| } |
| |
| const prefixRegexp = /^(-webkit-|-epub-|-apple-)(.+)$/; |
| |
| function createPropertyView(categoryObject, propertyObject) |
| { |
| function createLinkWithHeading(elementName, heading, linkText, linkUrl) |
| { |
| var container = document.createElement(elementName); |
| if (heading) { |
| container.textContent = heading + ": "; |
| } |
| var link = document.createElement("a"); |
| link.textContent = linkText; |
| link.href = linkUrl; |
| container.appendChild(link); |
| return container; |
| } |
| |
| function appendValueWithLink(container, value, link) |
| { |
| if (link) { |
| var anchor = document.createElement('a'); |
| anchor.href = link; |
| anchor.textContent = value; |
| container.appendChild(anchor); |
| return; |
| } |
| |
| container.textContent = value; |
| } |
| |
| function makeTwitterLink(twitterHandle) |
| { |
| if (twitterHandle[0] == "@") |
| twitterHandle = twitterHandle.substring(1); |
| return "https://twitter.com/" + twitterHandle; |
| } |
| |
| var hasSpecificationObject = "specification" in propertyObject; |
| var specificationObject = propertyObject.specification; |
| |
| var container = document.createElement('li'); |
| |
| container.className = "property"; |
| |
| var slug = propertyObject.name.toLowerCase().replace(/ /g, '-'); |
| container.setAttribute("id", "property-" + slug); |
| |
| var descriptionContainer = document.createElement('div'); |
| descriptionContainer.className = "property-description status-marker"; |
| |
| var featureHeaderContainer = document.createElement('div'); |
| featureHeaderContainer.className = "property-header"; |
| descriptionContainer.appendChild(featureHeaderContainer); |
| |
| var titleElement = document.createElement("h3"); |
| var anchorLinkElement = document.createElement("a"); |
| anchorLinkElement.href = "#" + container.getAttribute("id"); |
| anchorLinkElement.name = container.getAttribute("id"); |
| anchorLinkElement.textContent = propertyObject.name; |
| titleElement.appendChild(anchorLinkElement); |
| |
| if (categoryObject) { |
| if (specificationObject && ("url" in specificationObject || "obsolete-url" in specificationObject)) { |
| var url = ("url" in specificationObject) ? specificationObject.url : specificationObject['obsolete-url']; |
| var specSpan = createLinkWithHeading("span", null, categoryObject.shortname, specificationObject.url); |
| specSpan.className = 'spec-label'; |
| titleElement.appendChild(specSpan); |
| } else { |
| var labelSpan = document.createElement("span"); |
| labelSpan.className = 'spec-label'; |
| labelSpan.textContent = categoryObject.shortname; |
| titleElement.appendChild(labelSpan); |
| } |
| } |
| |
| featureHeaderContainer.appendChild(titleElement); |
| |
| var toggledContentContainer = document.createElement('div'); |
| toggledContentContainer.className = "toggleable"; |
| descriptionContainer.appendChild(toggledContentContainer); |
| |
| var aliases = propertyNameAliases(propertyObject); |
| if (aliases.length) { |
| var propertyAliasDiv = document.createElement('div'); |
| propertyAliasDiv.className = 'property-alias'; |
| propertyAliasDiv.textContent = 'Also supported as: ' + aliases.join(', '); |
| toggledContentContainer.appendChild(propertyAliasDiv); |
| } |
| |
| var longhands = propertyLonghands(propertyObject); |
| if (longhands.length) { |
| var longhandsDiv = document.createElement('div'); |
| longhandsDiv.className = 'longhands'; |
| |
| longhandsDiv.textContent = 'Shorthand for '; |
| |
| for (var i in longhands) { |
| if (i > 0) |
| longhandsDiv.appendChild(document.createTextNode(', ')); |
| var longhand = longhands[i]; |
| var longhandLink = document.createElement("a"); |
| longhandLink.href = "#property-" + longhand; |
| longhandLink.textContent = longhand; |
| longhandsDiv.appendChild(longhandLink); |
| } |
| |
| toggledContentContainer.appendChild(longhandsDiv); |
| } |
| |
| function collapsePrefixedValues(values) |
| { |
| var remainingValues = []; |
| var prefixMap = {}; |
| |
| for (var valueObj of values) { |
| var valueName = valueObj.value; |
| |
| var result = prefixRegexp.exec(valueName); |
| if (result) { |
| var unprefixed = result[2]; |
| var unprefixedValue = findValueByName(values, unprefixed); |
| if (unprefixedValue) { |
| (prefixMap[unprefixedValue.value] = prefixMap[unprefixedValue.value] || []).push(valueName); |
| continue; |
| } |
| } |
| |
| remainingValues.push(valueObj); |
| } |
| |
| for (var prefixed in prefixMap) { |
| var unprefixedValue = findValueByName(remainingValues, prefixed); |
| unprefixedValue.aliases = prefixMap[prefixed]; |
| } |
| |
| return remainingValues; |
| } |
| |
| if (propertyObject.values.length) { |
| var valuesHeader = document.createElement("h4"); |
| valuesHeader.textContent = 'Supported Values:'; |
| toggledContentContainer.appendChild(valuesHeader); |
| |
| var valuesList = document.createElement("ul"); |
| valuesList.className = 'values'; |
| |
| var values = collapsePrefixedValues(propertyObject.values); |
| for (var valueObj of values) { |
| var li = document.createElement("li"); |
| |
| valueObj.el = li; |
| |
| var link = undefined; |
| var valueAliases = undefined; |
| var status = undefined; |
| if ('aliases' in valueObj) |
| valueAliases = valueObj.aliases; |
| |
| if ('status' in valueObj) |
| status = valueObj.status; |
| |
| if ('url' in valueObj) |
| link = valueObj['url']; |
| |
| appendValueWithLink(li, valueObj.value, link); |
| |
| if (valueAliases) { |
| var span = document.createElement('span'); |
| span.textContent = ' (' + valueAliases.join(', ') + ')'; |
| span.className = 'value-alias'; |
| li.appendChild(span); |
| } |
| |
| if (status) { |
| var span = document.createElement('span'); |
| span.textContent = ' (' + status + ')'; |
| span.className = 'value-status'; |
| li.appendChild(span); |
| } |
| |
| valuesList.appendChild(li); |
| } |
| toggledContentContainer.appendChild(valuesList); |
| } |
| |
| var statusContainer = document.createElement("div"); |
| descriptionContainer.classList.add(propertyObject.status.status); |
| statusContainer.className = "property-status " + propertyObject.status.status; |
| var statusLabel = document.createElement("label"); |
| |
| if ("webkit-url" in propertyObject) { |
| var statusLink = document.createElement("a"); |
| statusLink.href = propertyObject["webkit-url"]; |
| statusLink.textContent = readableStatus[propertyObject.status.status]; |
| statusLabel.appendChild(statusLink); |
| } else { |
| statusLabel.textContent = readableStatus[propertyObject.status.status]; |
| } |
| statusContainer.appendChild(statusLabel); |
| featureHeaderContainer.appendChild(statusContainer); |
| |
| var toggle = document.createElement('button'); |
| toggle.className = 'toggle'; |
| |
| container.addEventListener('click', function (e) { |
| container.classList.toggle('opened'); |
| }); |
| |
| featureHeaderContainer.appendChild(toggle); |
| |
| if (specificationObject && "description" in specificationObject) { |
| var testDescription = document.createElement('p'); |
| testDescription.className = "property-desc"; |
| testDescription.innerHTML = specificationObject.description; |
| toggledContentContainer.appendChild(testDescription); |
| } |
| |
| if (specificationObject && "comment" in specificationObject) { |
| if ("description" in specificationObject) { |
| var hr = document.createElement("hr"); |
| hr.className = 'comment'; |
| toggledContentContainer.appendChild(hr); |
| } |
| var comment = document.createElement('p'); |
| comment.className = 'comment'; |
| comment.innerHTML = specificationObject.comment; |
| toggledContentContainer.appendChild(comment); |
| } |
| |
| if (propertyObject.status && "comment" in propertyObject.status) { |
| var comment = document.createElement('p'); |
| comment.className = 'comment'; |
| comment.innerHTML = propertyObject.status.comment; |
| toggledContentContainer.appendChild(comment); |
| } |
| |
| container.appendChild(descriptionContainer); |
| |
| function getMostSpecificProperty(categoryObject, specificationObject, attributeName) |
| { |
| // The url in the specification object is more specific, so use it if present. |
| if (specificationObject && attributeName in specificationObject) |
| return specificationObject[attributeName]; |
| |
| return categoryObject[attributeName]; |
| } |
| |
| var hasReferenceLink = categoryObject && "url" in categoryObject; |
| var hasDocumentationLink = (specificationObject && "documentation-url" in specificationObject) || (categoryObject && "documentation-url" in categoryObject); |
| var hasContactObject = specificationObject && "contact" in specificationObject; |
| |
| if (hasDocumentationLink || hasReferenceLink || hasContactObject) { |
| var moreInfoList = document.createElement("ul"); |
| moreInfoList.className = 'more-info'; |
| if (hasDocumentationLink) { |
| // The url in the specification object is more specific, so use it if present. |
| var url = getMostSpecificProperty(categoryObject, specificationObject, 'documentation-url'); |
| moreInfoList.appendChild(createLinkWithHeading("li", "Documentation", url, url)); |
| } |
| |
| if (hasReferenceLink) { |
| var url = getMostSpecificProperty(categoryObject, specificationObject, 'url'); |
| moreInfoList.appendChild(createLinkWithHeading("li", "Reference", url, url)); |
| |
| if ('obsolete-url' in specificationObject){ |
| var url = specificationObject['obsolete-url']; |
| moreInfoList.appendChild(createLinkWithHeading("li", "Reference", url, url)); |
| } |
| } |
| |
| if (hasContactObject) { |
| var li = document.createElement("li"); |
| li.textContent = "Contact: "; |
| var contactObject = specificationObject.contact; |
| if (contactObject.twitter) { |
| li.appendChild(createLinkWithHeading("span", null, contactObject.twitter, makeTwitterLink(contactObject.twitter))); |
| } |
| if (contactObject.email) { |
| if (contactObject.twitter) { |
| li.appendChild(document.createTextNode(" - ")); |
| } |
| var emailText = contactObject.email; |
| if (contactObject.name) { |
| emailText = contactObject.name; |
| } |
| li.appendChild(createLinkWithHeading("span", null, emailText, "mailto:" + contactObject.email)); |
| } |
| moreInfoList.appendChild(li); |
| } |
| |
| toggledContentContainer.appendChild(moreInfoList); |
| } |
| |
| return container; |
| } |
| |
| function canonicalizeIdentifier(identifier) |
| { |
| return identifier.toLocaleLowerCase().replace(/ /g, '-'); |
| } |
| |
| function renderSpecifications(categories, properties, selectedSpecifications) |
| { |
| var specificationsList = document.getElementById('specifications'); |
| specificationsList.addEventListener('change', function() { updateSearch(properties); }); |
| |
| var selectedIndex = -1; |
| var allCategories = Object.keys(categories).sort(); |
| |
| for (var i = 0; i < allCategories.length; ++i) { |
| var categoryKey = allCategories[i]; |
| var category = categories[categoryKey]; |
| categoryKey = canonicalizeIdentifier(categoryKey); |
| |
| var option = document.createElement("option"); |
| option.setAttribute('value', categoryKey); |
| if (selectedSpecifications.indexOf(categoryKey) != -1) |
| selectedIndex = i; |
| |
| option.appendChild(document.createTextNode(" " + category['shortname'])); |
| specificationsList.appendChild(option); |
| } |
| if (selectedIndex != -1) |
| specificationsList.selectedIndex = selectedIndex; |
| } |
| |
| function getPropertyCategory(propertyObject) |
| { |
| if ('specification' in propertyObject && 'category' in propertyObject.specification) |
| return propertyObject.specification.category; |
| |
| return undefined; |
| } |
| |
| function renderProperties(categories, propertyObjects) |
| { |
| var propertiesContainer = document.getElementById('properties-container'); |
| for (var propertyObject of propertyObjects) { |
| var category = getPropertyCategory(propertyObject); |
| propertiesContainer.appendChild(createPropertyView(categories[category], propertyObject)); |
| } |
| } |
| |
| function convertToTitleCase(string) |
| { |
| return string.replace(/\w\S*/g, function(txt){ |
| return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); |
| }); |
| } |
| |
| function initSearch(properties, categories) |
| { |
| var filtersForm = document.getElementById('property-filters'); |
| var filtersToggleButton = document.getElementsByClassName('filters-toggle-button')[0]; |
| var statusContainer = document.getElementById('status-filters'); |
| var inputField = document.getElementById('search'); |
| var featuresEls = document.querySelectorAll('.properties > li'); |
| var statusFilters = {}; |
| |
| properties.forEach(function(property, i) { |
| property.el = featuresEls[i]; |
| property.visible = true; |
| |
| // FIXME: need status per value as well. |
| if (property.status != undefined) { |
| propertyStatusKey = property.status.status.toLocaleLowerCase(); |
| |
| if (!statusFilters[propertyStatusKey]) |
| statusFilters[propertyStatusKey] = property.status.status; |
| |
| if (statusOrder.indexOf(propertyStatusKey) == -1) |
| window.console.log('Status ' + propertyStatusKey + ' is not one of the predefined status keys ', statusOrder); |
| } |
| }); |
| |
| var selectedStatuses = statusesFromURL(); |
| var selectedSpecs = specificationsFromURL(); |
| |
| for (var key of statusOrder) { |
| var status = statusFilters[key]; |
| var canonicalStatus = canonicalizeIdentifier(status); |
| |
| var entry = document.createElement("li"); |
| var label = document.createElement("label"); |
| var input = document.createElement("input"); |
| input.setAttribute('type','checkbox'); |
| input.setAttribute('value', canonicalStatus); |
| if (selectedStatuses.indexOf(canonicalStatus) != -1) { |
| filtersForm.classList.add('opened'); |
| input.checked = true; |
| } |
| input.className = 'status-checkbox'; |
| input.addEventListener('change', function() { updateSearch(properties); }); |
| label.appendChild(input); |
| label.className = "status-filter " + canonicalStatus; |
| label.appendChild(document.createTextNode(" " + readableStatus[status])); |
| entry.appendChild(label); |
| statusContainer.appendChild(entry); |
| } |
| |
| // Append the special "By Specification" checkbox |
| { |
| var entry = document.createElement("li"); |
| var label = document.createElement("label"); |
| var input = document.createElement("input"); |
| input.id = 'by-spec-checkbox'; |
| input.setAttribute('type','checkbox'); |
| if (selectedSpecs.length > 0) |
| input.checked = true; |
| input.addEventListener('change', function() { updateSearch(properties); }); |
| label.appendChild(input); |
| label.className = "status-filter by-specification"; |
| label.appendChild(document.createTextNode(" By Specification:")); |
| |
| var specsList = document.createElement('select'); |
| specsList.className = 'specifications'; |
| specsList.id = 'specifications'; |
| specsList.addEventListener('mousedown', function() { |
| input.setAttribute('checked','checked'); |
| input.checked = true; |
| console.log(input); |
| input.checked = true; |
| }); |
| var specsListToggle = document.createElement('div'); |
| specsListToggle.className = 'filter-by-specifications-toggle'; |
| label.appendChild(specsList); |
| label.appendChild(specsListToggle); |
| entry.appendChild(label); |
| |
| statusContainer.appendChild(entry); |
| } |
| |
| filtersToggleButton.addEventListener('mousedown', function (e) { |
| filtersForm.classList.toggle('opened'); |
| }); |
| |
| var searchTerm = searchTermFromURL(); |
| if (searchTerm.length) { |
| inputField.value = searchTerm; |
| inputField.placeholder = ''; |
| } |
| inputField.addEventListener('input', function() { updateSearch(properties); }); |
| |
| var inputs = [].slice.call(filtersForm.getElementsByTagName('input')); |
| inputs.forEach(function (input,i) { |
| input.addEventListener('click', function (e) { |
| e.stopPropagation(); |
| }); |
| }); |
| |
| renderSpecifications(categories, properties, selectedSpecs); |
| } |
| |
| function getValuesOfCheckedItems(items) |
| { |
| var checkedValues = []; |
| items.forEach(function(item,i) { |
| if (item.checked) |
| checkedValues.push(item.value); |
| }); |
| |
| return checkedValues; |
| } |
| |
| function getValuesOfSelectedItems(select) |
| { |
| var selectedValues = []; |
| |
| if (select.selectedIndex != -1) |
| selectedValues.push(select.options[select.selectedIndex].value); |
| |
| return selectedValues; |
| } |
| |
| function selectedSpecifications() |
| { |
| var specificationsList = document.getElementById('specifications'); |
| if (!document.getElementById('by-spec-checkbox').checked) { |
| specificationsList.disabled = true; |
| return []; |
| } |
| specificationsList.disabled = false; |
| return getValuesOfSelectedItems(specificationsList); |
| } |
| |
| function updateSearch(properties) |
| { |
| var inputField = document.getElementById('search'); |
| var statusContainer = document.getElementById('status-filters'); |
| |
| var searchTerm = inputField.value.trim().toLowerCase(); |
| var activeStatusFilters = getValuesOfCheckedItems([].slice.call(statusContainer.querySelectorAll('.status-checkbox'))); |
| |
| var prefixContainer = document.getElementById('prefix-filters'); |
| var activePrefixFilters = getValuesOfCheckedItems([].slice.call(prefixContainer.getElementsByTagName('input'))); |
| |
| var numVisible = searchProperties(properties, searchTerm, selectedSpecifications(), activeStatusFilters, activePrefixFilters); |
| document.getElementById('property-pluralize').textContent = numVisible == 1 ? 'property' : 'properties'; |
| document.getElementById('property-count').textContent = numVisible; |
| |
| updateSpecsState(); |
| updateURL(searchTerm, selectedSpecifications(), activeStatusFilters, activePrefixFilters); |
| } |
| |
| function updateSpecsState() |
| { |
| var specsEnabled = document.getElementById('by-spec-checkbox').checked; |
| var specificationsList = document.getElementById('specifications'); |
| |
| var radiobuttons = [].slice.call(specificationsList.getElementsByTagName('input')); |
| radiobuttons.forEach(function(radiobutton,i) { |
| radiobutton.disabled = !specsEnabled; |
| }); |
| } |
| |
| function updateURL(searchTerm, selectedSpecifications, activeStatusFilters, activePrefixFilters) |
| { |
| var searchString = ''; |
| |
| function appendDelimiter() |
| { |
| searchString += searchString.length ? '&' : '?'; |
| } |
| |
| if (searchTerm.length > 0) { |
| appendDelimiter(); |
| searchString += 'search=' + encodeURIComponent(searchTerm); |
| } |
| |
| if (activeStatusFilters.length) { |
| appendDelimiter(); |
| searchString += 'status=' + activeStatusFilters.join(','); |
| } |
| |
| if (selectedSpecifications.length) { |
| appendDelimiter(); |
| searchString += 'specs=' + selectedSpecifications.join(','); |
| } |
| |
| if (activePrefixFilters.length) { |
| appendDelimiter(); |
| searchString += 'prefix=' + activePrefixFilters.join(','); |
| } |
| |
| var current = window.location.href; |
| window.location.href = current.replace(/#(.*)$/, '') + '#' + searchString; |
| } |
| |
| function searchTermFromURL() |
| { |
| var search = window.location.search; |
| var searchRegExp = /\#.*search=([^&]+)/; |
| |
| var result; |
| if (result = window.location.href.match(searchRegExp)) |
| return decodeURIComponent(result[1]); |
| |
| return ''; |
| } |
| |
| function statusesFromURL() |
| { |
| var search = window.location.search; |
| var statusRegExp = /\#.*status=([^&]+)/; |
| |
| var result; |
| if (result = window.location.href.match(statusRegExp)) |
| return result[1].split(','); |
| |
| return []; |
| } |
| |
| function specificationsFromURL() |
| { |
| var search = window.location.search; |
| var specsRegExp = /\#.*specs=([^&]+)/; |
| |
| var result; |
| if (result = window.location.href.match(specsRegExp)) |
| return result[1].split(','); |
| |
| return []; |
| } |
| |
| function valueOrAliasIsPrefixed(valueObj) |
| { |
| if (prefixRegexp.exec(valueObj.value)) |
| return true; |
| |
| if ('alias' in valueObj) { |
| for (var alias of valueObj.aliases) { |
| if (prefixRegexp.exec(alias)) |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| function filterValues(propertyObject, searchTerm, categories, statusFilters) |
| { |
| for (var valueObj of propertyObject.values) { |
| if (!valueObj.el) |
| continue; |
| |
| var visible = false; |
| visible = valueObj.value.toLowerCase().indexOf(searchTerm) !== -1; |
| |
| if (!visible) { |
| for (var currValueObj of propertyObject.values) { |
| if (valueOrAliasIsPrefixed(currValueObj)) { |
| visible = true; |
| break; |
| } |
| } |
| } |
| |
| if (!visible) { |
| for (var currValueObj of propertyObject.values) { |
| if (prefixRegexp.exec(currValueObj.value)) { |
| visible = true; |
| break; |
| } |
| } |
| } |
| |
| if (visible) |
| valueObj.el.classList.remove('hidden'); |
| else |
| valueObj.el.classList.add('hidden'); |
| } |
| } |
| |
| function searchProperties(properties, searchTerm, categories, statusFilters, prefixFilters) |
| { |
| var visibleCount = 0; |
| properties.forEach(function(propertyObject) { |
| var matchesStatusSearch = isStatusFiltered(propertyObject, statusFilters); |
| var matchesPrefixSearch = isPrefixFiltered(propertyObject, prefixFilters); |
| |
| var visible = propertyIsSearchMatch(propertyObject, searchTerm) && isCategoryMatch(propertyObject, categories) && matchesStatusSearch && matchesPrefixSearch; |
| if (visible && !propertyObject.visible) |
| propertyObject.el.className = 'property'; |
| else if (!visible && propertyObject.visible) |
| propertyObject.el.className = 'property is-hidden'; |
| |
| if (visible) { |
| filterValues(propertyObject, searchTerm); |
| ++visibleCount; |
| } |
| |
| propertyObject.visible = visible; |
| }); |
| |
| return visibleCount; |
| } |
| |
| function propertyIsSearchMatch(propertyObject, searchTerm) |
| { |
| if (searchTerm.length == 0) |
| return true; |
| |
| if (propertyObject.name.toLowerCase().indexOf(searchTerm) !== -1) |
| return true; |
| |
| if ('keywords' in propertyObject) { |
| for (var keyword of propertyObject.keywords) { |
| if (keyword.toLowerCase().indexOf(searchTerm) !== -1) |
| return true; |
| } |
| } |
| |
| for (var valueObj of propertyObject.values) { |
| if (valueObj.value.toLowerCase().indexOf(searchTerm) !== -1) |
| return true; |
| } |
| |
| return false; |
| } |
| |
| function getSpecificationCategory(propertyObject) |
| { |
| if ('specification' in propertyObject) { |
| var specification = propertyObject.specification; |
| if ('category' in specification) { |
| return specification.category; |
| } |
| } |
| return undefined; |
| } |
| |
| function getSpecificationObsoleteCategory(propertyObject) |
| { |
| if ('specification' in propertyObject) { |
| var specification = propertyObject.specification; |
| if ('obsolete-category' in specification) { |
| return specification['obsolete-category']; |
| } |
| } |
| return undefined; |
| } |
| |
| function isCategoryMatch(propertyObject, categories) |
| { |
| if (!categories.length) |
| return true; |
| |
| var category; |
| if (category = getSpecificationCategory(propertyObject)) { |
| if (categories.indexOf(category) !== -1) { |
| return true; |
| } |
| } |
| |
| if (category = getSpecificationObsoleteCategory(propertyObject)) { |
| if (categories.indexOf(category) !== -1) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| function propertyOrAliasIsPrefixed(propertyObject) |
| { |
| if (prefixRegexp.exec(propertyObject.name)) |
| return true; |
| |
| for (var alias of propertyNameAliases(propertyObject)) { |
| if (prefixRegexp.exec(alias)) |
| return true; |
| } |
| |
| return false; |
| } |
| |
| function isStatusFiltered(propertyObject, activeFilters) |
| { |
| if (activeFilters.length == 0) |
| return true; |
| if (propertyObject.status === undefined) |
| return false; |
| if (activeFilters.indexOf(propertyObject.status.status) !== -1) |
| return true; |
| |
| return false; |
| } |
| |
| function isPrefixFiltered(propertyObject, activeFilters) |
| { |
| if (activeFilters.length == 0) |
| return true; |
| |
| if (activeFilters.indexOf('prefix-only-property') !== -1) |
| return prefixRegexp.exec(propertyObject.name); |
| |
| if (activeFilters.indexOf('prefix-supported-property') !== -1) |
| return propertyOrAliasIsPrefixed(propertyObject); |
| |
| if (activeFilters.indexOf('prefix-supported-value') !== -1) { |
| for (var valueObj of propertyObject.values) { |
| if (valueOrAliasIsPrefixed(valueObj)) |
| return true; |
| } |
| } |
| |
| if (activeFilters.indexOf('prefix-only-value') !== -1) { |
| for (var valueObj of propertyObject.values) { |
| if (prefixRegexp.exec(valueObj.value)) |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| function findValueByName(values, name) |
| { |
| return values.find(function(element) { |
| return element.value === name; |
| }) |
| } |
| |
| function mergeProperties(unprefixedPropertyObj, prefixedPropertyObj) |
| { |
| (unprefixedPropertyObj['codegen-properties'].aliases = unprefixedPropertyObj['codegen-properties'].aliases || []).push(prefixedPropertyObj.name); |
| |
| for (var valueObj of prefixedPropertyObj.values) { |
| if (!findValueByName(unprefixedPropertyObj.values, valueObj.value)) |
| prefixedPropertyObj.values.push(valueObj); |
| } |
| |
| return unprefixedPropertyObj; |
| } |
| |
| // Sometimes we have separate entries for -webkit-foo and foo. |
| function collapsePrefixedProperties(properties) |
| { |
| function findPropertyByName(properties, name) |
| { |
| return properties.find(function(element) { |
| return element.name === name; |
| }) |
| } |
| |
| var remainingProperties = []; |
| var prefixMap = {}; |
| |
| for (var propertyObj of properties) { |
| var propertyName = propertyObj.name; |
| |
| var result = prefixRegexp.exec(propertyName); |
| if (result) { |
| var unprefixed = result[2]; |
| var unprefixedProperty = findPropertyByName(properties, unprefixed); |
| if (unprefixedProperty) { |
| mergeProperties(unprefixedProperty, propertyObj); |
| continue; |
| } |
| } |
| |
| remainingProperties.push(propertyObj); |
| } |
| |
| return remainingProperties; |
| } |
| |
| function canonicalizeValues(propertyObject) |
| { |
| var valueObjects = []; |
| // Convert all values to objects. |
| if ('values' in propertyObject) { |
| for (var value of propertyObject.values) { |
| if (typeof value === 'object') |
| valueObjects.push(value); |
| else |
| valueObjects.push({ 'value' : value }); |
| } |
| } |
| propertyObject.values = valueObjects; |
| } |
| |
| function canonicalizeStatus(propertyObject, categories) |
| { |
| // Inherit "status" from the category if not explicitly specified. |
| if (!('status' in propertyObject)) { |
| var category = getSpecificationCategory(propertyObject) |
| if (category) { |
| var categoryObject = categories[category]; |
| if (categoryObject) { |
| if ('status' in categoryObject) { |
| propertyObject.status = { |
| 'status' : categoryObject.status |
| }; |
| } |
| } |
| } |
| } else { |
| // Convert all values to objects. |
| if (typeof propertyObject.status === 'string') |
| propertyObject.status = { 'status': propertyObject.status }; |
| } |
| |
| if (!('status' in propertyObject)) { |
| propertyObject.status = { |
| 'status' : 'supported', |
| 'enabled-by-default' : true |
| }; |
| } else if (!('status' in propertyObject.status)) |
| propertyObject.status.status = 'supported'; |
| |
| propertyObject.status.status = canonicalizeIdentifier(propertyObject.status.status); |
| } |
| |
| function renderContent(results) |
| { |
| var mainContent = document.getElementById("property-list"); |
| var successSubtree = document.importNode(document.getElementById("success-template").content, true); |
| mainContent.appendChild(successSubtree); |
| |
| var properties = results[0]['properties']; |
| var everythingToShow = []; |
| |
| var categories = results[0]['categories']; |
| |
| for (var property in properties) { |
| var propertyObject = properties[property]; |
| propertyObject.name = property; |
| |
| canonicalizeValues(propertyObject); |
| canonicalizeStatus(propertyObject, categories); |
| |
| everythingToShow.push(propertyObject); |
| } |
| |
| everythingToShow = collapsePrefixedProperties(everythingToShow); |
| sortAlphabetically(everythingToShow); |
| |
| renderProperties(categories, everythingToShow); |
| |
| initSearch(everythingToShow, categories); |
| |
| updateSearch(everythingToShow); |
| } |
| |
| function displayError(error) |
| { |
| window.console.log('displayError', error) |
| var mainContent = document.getElementById("property-list"); |
| var successSubtree = document.importNode(document.getElementById("error-template").content, true); |
| |
| var errorMessage = "Unable to load " + error.url; |
| |
| if (error.request.status !== 200) { |
| errorMessage += ", status: " + error.request.status + " - " + error.request.statusText; |
| } else if (!error.response) { |
| errorMessage += ", the JSON file cannot be processed."; |
| } |
| |
| successSubtree.querySelector("#error-message").textContent = errorMessage; |
| |
| mainContent.appendChild(successSubtree); |
| } |
| |
| Promise.all([loadCSSProperties]).then(renderContent).catch(displayError); |
| } |
| |
| document.addEventListener("DOMContentLoaded", initializeStatusPage); |
| </script> |
| |
| <?php get_footer(); ?> |