Skip to content

XML vs. XHTML: Understanding the Key Differences

XML and XHTML, while sharing a common ancestry in markup languages, serve distinct purposes and adhere to different sets of rules. Understanding their differences is crucial for web developers and anyone involved in data structuring and presentation.

At their core, both are markup languages designed to structure and transport data. However, their strictness and intended applications diverge significantly.

XML, the eXtensible Markup Language, is a meta-language designed for describing data. Its primary focus is on the *what* of the data – its structure, content, and meaning – rather than its visual presentation. This makes it incredibly versatile for data exchange across different systems and platforms.

The Foundation of XML: Extensibility and Data Integrity

XML’s strength lies in its extensibility. Developers can create their own tags and attributes, defining custom vocabularies to represent virtually any type of information. This flexibility allows for the creation of highly specific data formats tailored to particular industries or applications.

The strict syntax rules of XML ensure data integrity and consistency. Every opening tag must have a corresponding closing tag, elements must be properly nested, and attribute values must be quoted. This well-formedness is essential for automated processing by machines.

For instance, consider a simple XML document representing a book. It might include tags like ``, ``, `<author>`, and `<isbn>`. This structure clearly defines the data and its relationships, making it easily readable and parsable by software.</p> <h3>Key Characteristics of XML</h3> <p>XML documents are inherently hierarchical, resembling a tree structure. This nested format is fundamental to how XML organizes and represents relationships between data elements.</p> <p>The language is case-sensitive, meaning `<Book>` is treated as different from `<book>`. This precision is vital for unambiguous interpretation by parsing software.</p> <p>XML is designed to be human-readable and machine-readable. While its primary purpose is data transport and storage, its clear structure allows developers to understand the data’s organization without complex tools.</p> <p>It is a W3C recommendation, signifying its status as a standard for structured data. This standardization promotes interoperability between diverse systems.</p> <p>The extensibility of XML means it can be adapted for various uses, from configuration files and data feeds to complex application data storage. Its abstract nature allows it to transcend specific presentation requirements.</p> <h2>Enter XHTML: Bridging the Gap Between XML and HTML</h2> <p>XHTML, the eXtensible HyperText Markup Language, is essentially an XML-based reformulation of HTML. It was developed to make HTML more structured, robust, and compliant with XML’s stricter syntax rules.</p> <p>The goal was to create a version of HTML that could be parsed more easily by XML parsers, thereby improving interoperability and enabling richer multimedia integration. This also paved the way for more advanced web applications.</p> <p>XHTML aims to combine the power of XML’s strictness and extensibility with the ubiquitous nature of HTML for web page presentation.</p> <h3>XHTML’s Relationship with HTML</h3> <p>XHTML is a direct descendant of HTML, designed to be a stricter, more XML-compliant version. It inherits HTML’s core functionality for structuring web content but enforces XML’s syntax rules.</p> <p>This means that while you can create a web page using XHTML, it must adhere to XML’s well-formedness rules. This includes closing all tags, properly nesting elements, and using lowercase for all tags and attributes.</p> <p>The transition from HTML to XHTML was intended to make web pages more accessible and easier to process by a wider range of devices and applications, not just traditional web browsers.</p> <h3>Syntax Differences: The Crucial Distinctions</h3> <p>Perhaps the most significant difference lies in syntax enforcement. XML is inherently strict, requiring well-formed documents. XHTML inherits this strictness, making it more rigid than traditional HTML.</p> <p>In HTML, tags can sometimes be omitted (e.g., closing `</p> <p>` tags). In XHTML, all tags must be explicitly closed, including self-closing tags like `<br />` and `<img decoding="async" src="..." alt="..." />`.</p> <p>Attribute values in XHTML must always be enclosed in quotes, even if they appear to be simple values. For example, `width=”600″` is correct, whereas `width=600` would be invalid in XHTML.</p> <p>HTML is case-insensitive, but XHTML is case-sensitive. All tags and attributes in XHTML must be in lowercase. This aligns with XML’s case-sensitive nature.</p> <p>Empty elements, which in HTML might be written as `<br />`, must be written in XHTML as `<br />`. This self-closing syntax is a direct carryover from XML’s requirements.</p> <h4>Practical Examples of XHTML Syntax</h4> <p>Consider a simple paragraph element. In HTML, it might be written as `</p> <p>This is a paragraph.</p> <p>` or even `</p> <p>This is a paragraph.`. In XHTML, it must be `</p> <p>This is a paragraph.</p> <p>`.</p> <p>An image tag in HTML is typically `<img decoding="async" src="image.jpg" alt="An image">`. In XHTML, it becomes `<img decoding="async" src="image.jpg" alt="An image" />`. The trailing slash is mandatory.</p> <p>A link in HTML might look like `<a href="page.html">Link</a>`. In XHTML, it remains `<a href="page.html">Link</a>`. The structure is similar, but the overall document must conform to XML rules.</p> <h2>Purpose and Application: Where They Shine</h2> <p>XML’s primary purpose is to structure and transport data. It’s the backbone of many data exchange formats, configuration files, and content management systems. Think of RSS feeds, Atom feeds, or configuration files for software applications.</p> <p>Its ability to define custom tags makes it ideal for situations where specific data semantics are paramount, regardless of how that data will eventually be displayed. This is crucial for enterprise-level data management and inter-application communication.</p> <p>XHTML, on the other hand, is specifically designed for web page markup. It aims to provide a more robust and future-proof foundation for the World Wide Web, ensuring that web content is well-formed and can be processed by a wider array of devices and technologies.</p> <h3>XML’s Use Cases</h3> <p>Data interchange between disparate systems is a cornerstone application. Companies can define XML schemas to ensure that data exchanged between different departments or even different organizations is consistently formatted and understood.</p> <p>Configuration files for software often use XML. This allows developers to easily define settings and parameters in a structured and human-readable format.</p> <p>Content syndication, such as RSS and Atom, relies heavily on XML to distribute articles and updates across the web.</p> <p>Databases and document storage systems can leverage XML for its structured nature, enabling efficient querying and manipulation of data.</p> <p>Markup for specific domains, like MathML for mathematical notation or SVG for vector graphics, demonstrates XML’s power in creating specialized languages.</p> <h3>XHTML’s Role in Web Development</h3> <p>XHTML was intended to be the future of HTML, offering improved accessibility, easier parsing by machines, and better integration with other XML-based technologies like XSLT and XML Schema. Its stricter syntax was meant to eliminate common HTML errors that could lead to rendering inconsistencies across browsers.</p> <p>It was particularly beneficial for mobile devices and emerging technologies that required more predictable and structured data. The goal was to create a web that was more robust and less prone to the quirks of older HTML versions.</p> <p>However, the web has evolved, and the direct adoption of XHTML as a replacement for HTML has been superseded by HTML5, which reintroduces some of the flexibility of HTML while incorporating many of the structural benefits that XHTML aimed to provide.</p> <h2>Parsing and Validation: The Rigor of XML vs. XHTML</h2> <p>XML parsers are designed to strictly enforce the well-formedness rules of XML. If an XML document violates these rules, a parser will typically throw an error and refuse to process it.</p> <p>XHTML, being an XML application, also requires strict parsing. This means that an XHTML document must be well-formed according to XML rules to be considered valid XHTML. This strictness aids in creating predictable rendering behavior.</p> <p>Validation is another key differentiator. XML documents can be validated against a Document Type Definition (DTD) or an XML Schema (XSD) to ensure they not only are well-formed but also adhere to a specific structure and content rules defined by the schema.</p> <h3>XML Validation</h3> <p>Validation in XML ensures that a document conforms to a predefined structure and set of rules. This is achieved through DTDs or XSDs, which act as blueprints for the XML document.</p> <p>A DTD specifies the elements, attributes, and their relationships within an XML document. It defines the allowed content for each element and the order in which elements should appear.</p> <p>XML Schemas (XSDs) are more powerful than DTDs, offering more data types, namespaces, and complex schema definitions. They provide a more robust way to define the structure and content constraints of XML documents.</p> <p>Validating an XML document against its schema or DTD is crucial for ensuring data quality and consistency, especially in large-scale data exchange scenarios.</p> <h3>XHTML Validation</h3> <p>XHTML validation involves checking if an XHTML document is both well-formed (according to XML rules) and valid according to an XHTML DTD. This ensures that the document adheres to the specific structure and elements defined for XHTML.</p> <p>A valid XHTML document not only follows the strict syntax but also uses the correct XHTML elements and attributes as specified by its associated DTD. This level of validation was a key selling point for XHTML, promising more reliable web pages.</p> <p>Modern web development, however, has largely shifted towards HTML5, which has a different validation approach. While HTML5 documents can be validated, the process is less about strict XML well-formedness and more about conforming to HTML5 specifications.</p> <h2>The Evolution and Current Relevance</h2> <p>While XHTML offered significant advantages in terms of structure and interoperability, its strictness also presented challenges for web developers accustomed to HTML’s leniency. The transition wasn’t always smooth.</p> <p>The advent of HTML5, with its improved features, better error handling, and more forgiving parsing, has somewhat eclipsed the direct adoption of XHTML for new web development projects. HTML5 has effectively adopted many of the benefits XHTML aimed for without the same level of syntactic rigidity.</p> <p>However, XML remains a cornerstone of data structuring and exchange across the digital landscape. Its principles of extensibility and well-formedness continue to influence how data is managed and transmitted.</p> <h3>The Dominance of HTML5</h3> <p>HTML5 has become the de facto standard for web page creation. It addresses many of the limitations of previous HTML versions and offers a more practical and robust set of features for modern web applications.</p> <p>Its native support for multimedia, advanced form controls, and semantic elements has made it a compelling choice for developers. The parsing rules of HTML5 are more forgiving, making it easier to work with imperfectly formed markup.</p> <p>While HTML5 doesn’t strictly enforce XML’s well-formedness, it has incorporated many of the structural and semantic improvements that XHTML championed.</p> <h3>The Enduring Power of XML</h3> <p>Despite the rise of HTML5 for web content, XML’s role in data structuring and exchange remains indispensable. Its ability to define custom vocabularies makes it a powerful tool for diverse applications.</p> <p>From enterprise systems and cloud services to configuration files and data feeds, XML continues to be a fundamental technology. Its focus on data semantics over presentation ensures its relevance in a data-driven world.</p> <p>Understanding XML is therefore crucial for anyone involved in software development, data engineering, or web services. It provides a universal language for describing and transporting information.</p> <h2>Conclusion: Choosing the Right Tool</h2> <p>In summary, XML is a meta-language for defining structured data, emphasizing extensibility and data integrity. Its primary use is for data representation and exchange.</p> <p>XHTML is a stricter, XML-compliant version of HTML, designed for web page markup. It aimed to bring the robustness of XML to the web, but its role has largely been superseded by HTML5 for new web development.</p> <p>The choice between them depends entirely on the task at hand: use XML for structuring and transporting data, and rely on HTML5 for modern web page creation, understanding that XHTML was a significant step in the evolution of web standards.</p> </article> </div> <div id="comments" class="comments-area"> <div id="respond" class="comment-respond nv-is-boxed"> <h2 id="reply-title" class="comment-reply-title">Leave a Reply <small><a rel="nofollow" id="cancel-comment-reply-link" href="/xml-vs-xhtml-understanding-the-key-differences/#respond" style="display:none;">Cancel reply</a></small></h2><form action="https://spellingmatters.blog/wp-comments-post.php" method="post" id="commentform" class="comment-form"><p class="comment-notes"><span id="email-notes">Your email address will not be published.</span> <span class="required-field-message">Required fields are marked <span class="required">*</span></span></p><p class="comment-form-author"><label for="author">Name <span class="required">*</span></label> <input id="author" name="author" type="text" value="" size="30" maxlength="245" autocomplete="name" required /></p> <p class="comment-form-email"><label for="email">Email <span class="required">*</span></label> <input id="email" name="email" type="email" value="" size="30" maxlength="100" aria-describedby="email-notes" autocomplete="email" required /></p> <p class="comment-form-url"><label for="url">Website</label> <input id="url" name="url" type="url" value="" size="30" maxlength="200" autocomplete="url" /></p> <p class="comment-form-comment"><label for="comment">Comment <span class="required">*</span></label> <textarea id="comment" name="comment" cols="45" rows="8" maxlength="65525" required></textarea></p><p class="comment-form-cookies-consent"><input id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes" /> <label for="wp-comment-cookies-consent">Save my name, email, and website in this browser for the next time I comment.</label></p> <p class="form-submit"><input name="submit" type="submit" id="submit" class="button button-primary" value="Post Comment" /> <input type='hidden' name='comment_post_ID' value='2341' id='comment_post_ID' /> <input type='hidden' name='comment_parent' id='comment_parent' value='0' /> </p></form> </div><!-- #respond --> </div> </article> </div> </div> </main><!--/.neve-main--> <button tabindex="0" id="scroll-to-top" class="scroll-to-top scroll-to-top-right scroll-show-mobile icon" aria-label="Scroll To Top"><svg class="scroll-to-top-icon" aria-hidden="true" role="img" xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 15 15"><rect width="15" height="15" fill="none"/><path fill="currentColor" d="M2,8.48l-.65-.65a.71.71,0,0,1,0-1L7,1.14a.72.72,0,0,1,1,0l5.69,5.7a.71.71,0,0,1,0,1L13,8.48a.71.71,0,0,1-1,0L8.67,4.94v8.42a.7.7,0,0,1-.7.7H7a.7.7,0,0,1-.7-.7V4.94L3,8.47a.7.7,0,0,1-1,0Z"/></svg></button><footer class="site-footer" id="site-footer" > <div class="hfg_footer"> <div class="footer--row footer-bottom layout-full-contained" id="cb-row--footer-desktop-bottom" data-row-id="bottom" data-show-on="desktop"> <div class="footer--row-inner footer-bottom-inner footer-content-wrap"> <div class="container"> <div class="hfg-grid nv-footer-content hfg-grid-bottom row--wrapper row " data-section="hfg_footer_layout_bottom" > <div class="hfg-slot left"><div class="builder-item cr"><div class="item--inner"><div class="component-wrap"><div><p><a href="https://themeisle.com/themes/neve/" rel="nofollow">Neve</a> | Powered by <a href="https://wordpress.org" rel="nofollow">WordPress</a></p></div></div></div></div></div><div class="hfg-slot c-left"></div><div class="hfg-slot center"></div> </div> </div> </div> </div> </div> </footer> </div><!--/.wrapper--> <script type="speculationrules"> {"prefetch":[{"source":"document","where":{"and":[{"href_matches":"/*"},{"not":{"href_matches":["/wp-*.php","/wp-admin/*","/wp-content/uploads/*","/wp-content/*","/wp-content/plugins/*","/wp-content/themes/neve/*","/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]} </script> <script> // Do not change this comment line otherwise Speed Optimizer won't be able to detect this script (function () { function sendRequest(url, body) { if(!window.fetch) { const xhr = new XMLHttpRequest(); xhr.open("POST", url, true); xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); xhr.send(JSON.stringify(body)) return } const request = fetch(url, { method: 'POST', body: JSON.stringify(body), keepalive: true, headers: { 'Content-Type': 'application/json;charset=UTF-8' } }); } const calculateParentDistance = (child, parent) => { let count = 0; let currentElement = child; // Traverse up the DOM tree until we reach parent or the top of the DOM while (currentElement && currentElement !== parent) { currentElement = currentElement.parentNode; count++; } // If parent was not found in the hierarchy, return -1 if (!currentElement) { return -1; // Indicates parent is not an ancestor of element } return count; // Number of layers between element and parent } const isMatchingClass = (linkRule, href, classes, ids) => { return classes.includes(linkRule.value) } const isMatchingId = (linkRule, href, classes, ids) => { return ids.includes(linkRule.value) } const isMatchingDomain = (linkRule, href, classes, ids) => { if(!URL.canParse(href)) { return false } const url = new URL(href) const host = url.host const hostsToMatch = [host] if(host.startsWith('www.')) { hostsToMatch.push(host.substring(4)) } else { hostsToMatch.push('www.' + host) } return hostsToMatch.includes(linkRule.value) } const isMatchingExtension = (linkRule, href, classes, ids) => { if(!URL.canParse(href)) { return false } const url = new URL(href) return url.pathname.endsWith('.' + linkRule.value) } const isMatchingSubdirectory = (linkRule, href, classes, ids) => { if(!URL.canParse(href)) { return false } const url = new URL(href) return url.pathname.startsWith('/' + linkRule.value + '/') } const isMatchingProtocol = (linkRule, href, classes, ids) => { if(!URL.canParse(href)) { return false } const url = new URL(href) return url.protocol === linkRule.value + ':' } const isMatchingExternal = (linkRule, href, classes, ids) => { if(!URL.canParse(href) || !URL.canParse(document.location.href)) { return false } const matchingProtocols = ['http:', 'https:'] const siteUrl = new URL(document.location.href) const linkUrl = new URL(href) // Links to subdomains will appear to be external matches according to JavaScript, // but the PHP rules will filter those events out. return matchingProtocols.includes(linkUrl.protocol) && siteUrl.host !== linkUrl.host } const isMatch = (linkRule, href, classes, ids) => { switch (linkRule.type) { case 'class': return isMatchingClass(linkRule, href, classes, ids) case 'id': return isMatchingId(linkRule, href, classes, ids) case 'domain': return isMatchingDomain(linkRule, href, classes, ids) case 'extension': return isMatchingExtension(linkRule, href, classes, ids) case 'subdirectory': return isMatchingSubdirectory(linkRule, href, classes, ids) case 'protocol': return isMatchingProtocol(linkRule, href, classes, ids) case 'external': return isMatchingExternal(linkRule, href, classes, ids) default: return false; } } const track = (element) => { const href = element.href ?? null const classes = Array.from(element.classList) const ids = [element.id] const linkRules = [{"type":"extension","value":"pdf"},{"type":"extension","value":"zip"},{"type":"protocol","value":"mailto"},{"type":"protocol","value":"tel"}] if(linkRules.length === 0) { return } // For link rules that target an id, we need to allow that id to appear // in any ancestor up to the 7th ancestor. This loop looks for those matches // and counts them. linkRules.forEach((linkRule) => { if(linkRule.type !== 'id') { return; } const matchingAncestor = element.closest('#' + linkRule.value) if(!matchingAncestor || matchingAncestor.matches('html, body')) { return; } const depth = calculateParentDistance(element, matchingAncestor) if(depth < 7) { ids.push(linkRule.value) } }); // For link rules that target a class, we need to allow that class to appear // in any ancestor up to the 7th ancestor. This loop looks for those matches // and counts them. linkRules.forEach((linkRule) => { if(linkRule.type !== 'class') { return; } const matchingAncestor = element.closest('.' + linkRule.value) if(!matchingAncestor || matchingAncestor.matches('html, body')) { return; } const depth = calculateParentDistance(element, matchingAncestor) if(depth < 7) { classes.push(linkRule.value) } }); const hasMatch = linkRules.some((linkRule) => { return isMatch(linkRule, href, classes, ids) }) if(!hasMatch) { return } const url = "https://spellingmatters.blog/wp-content/plugins/independent-analytics/iawp-click-endpoint.php"; const body = { href: href, classes: classes.join(' '), ids: ids.join(' '), ...{"payload":{"resource":"singular","singular_id":2341,"page":1},"signature":"08634a91c7d7a8083b5c4f9ac5bbe7a7"} }; sendRequest(url, body) } document.addEventListener('mousedown', function (event) { if (navigator.webdriver || /bot|crawler|spider|crawling|semrushbot|chrome-lighthouse/i.test(navigator.userAgent)) { return; } const element = event.target.closest('a') if(!element) { return } const isPro = false if(!isPro) { return } // Don't track left clicks with this event. The click event is used for that. if(event.button === 0) { return } track(element) }) document.addEventListener('click', function (event) { if (navigator.webdriver || /bot|crawler|spider|crawling|semrushbot|chrome-lighthouse/i.test(navigator.userAgent)) { return; } const element = event.target.closest('a, button, input[type="submit"], input[type="button"]') if(!element) { return } const isPro = false if(!isPro) { return } track(element) }) document.addEventListener('play', function (event) { if (navigator.webdriver || /bot|crawler|spider|crawling|semrushbot|chrome-lighthouse/i.test(navigator.userAgent)) { return; } const element = event.target.closest('audio, video') if(!element) { return } const isPro = false if(!isPro) { return } track(element) }, true) document.addEventListener("DOMContentLoaded", function (e) { if (document.hasOwnProperty("visibilityState") && document.visibilityState === "prerender") { return; } if (navigator.webdriver || /bot|crawler|spider|crawling|semrushbot|chrome-lighthouse/i.test(navigator.userAgent)) { return; } let referrer_url = null; if (typeof document.referrer === 'string' && document.referrer.length > 0) { referrer_url = document.referrer; } const params = location.search.slice(1).split('&').reduce((acc, s) => { const [k, v] = s.split('='); return Object.assign(acc, {[k]: v}); }, {}); const url = "https://spellingmatters.blog/wp-json/iawp/search"; const body = { referrer_url, utm_source: params.utm_source, utm_medium: params.utm_medium, utm_campaign: params.utm_campaign, utm_term: params.utm_term, utm_content: params.utm_content, gclid: params.gclid, ...{"payload":{"resource":"singular","singular_id":2341,"page":1},"signature":"08634a91c7d7a8083b5c4f9ac5bbe7a7"} }; sendRequest(url, body) }); })(); </script> <script id="neve-script-js-extra"> var NeveProperties = {"ajaxurl":"https://spellingmatters.blog/wp-admin/admin-ajax.php","nonce":"8fbc5469fd","isRTL":"","isCustomize":""}; //# sourceURL=neve-script-js-extra </script> <script src="https://spellingmatters.blog/wp-content/themes/neve/assets/js/build/modern/frontend.js?ver=4.2.2" id="neve-script-js" async></script> <script id="neve-script-js-after"> var html = document.documentElement; var theme = html.getAttribute('data-neve-theme') || 'light'; var variants = {"logo":{"light":{"src":false,"srcset":false,"sizes":false},"dark":{"src":false,"srcset":false,"sizes":false},"same":true}}; function setCurrentTheme( theme ) { var pictures = document.getElementsByClassName( 'neve-site-logo' ); for(var i = 0; i<pictures.length; i++) { var picture = pictures.item(i); if( ! picture ) { continue; }; var fileExt = picture.src.slice((Math.max(0, picture.src.lastIndexOf(".")) || Infinity) + 1); if ( fileExt === 'svg' ) { picture.removeAttribute('width'); picture.removeAttribute('height'); picture.style = 'width: var(--maxwidth)'; } var compId = picture.getAttribute('data-variant'); if ( compId && variants[compId] ) { var isConditional = variants[compId]['same']; if ( theme === 'light' || isConditional || variants[compId]['dark']['src'] === false ) { picture.src = variants[compId]['light']['src']; picture.srcset = variants[compId]['light']['srcset'] || ''; picture.sizes = variants[compId]['light']['sizes']; continue; }; picture.src = variants[compId]['dark']['src']; picture.srcset = variants[compId]['dark']['srcset'] || ''; picture.sizes = variants[compId]['dark']['sizes']; }; }; }; var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { if (mutation.type == 'attributes') { theme = html.getAttribute('data-neve-theme'); setCurrentTheme(theme); }; }); }); observer.observe(html, { attributes: true }); function toggleAriaClick() { function toggleAriaExpanded(toggle = 'true') { document.querySelectorAll('button.navbar-toggle').forEach(function(el) { if ( el.classList.contains('caret-wrap') ) { return; } el.setAttribute('aria-expanded', 'true' === el.getAttribute('aria-expanded') ? 'false' : toggle); }); } toggleAriaExpanded(); if ( document.body.hasAttribute('data-ftrap-listener') ) { return; } document.body.setAttribute('data-ftrap-listener', 'true'); document.addEventListener('ftrap-end', function() { toggleAriaExpanded('false'); }); } //# sourceURL=neve-script-js-after </script> <script src="https://spellingmatters.blog/wp-includes/js/comment-reply.min.js?ver=6.9.4" id="comment-reply-js" async data-wp-strategy="async" fetchpriority="low"></script> <script id="neve-scroll-to-top-js-extra"> var neveScrollOffset = {"offset":"0"}; //# sourceURL=neve-scroll-to-top-js-extra </script> <script src="https://spellingmatters.blog/wp-content/themes/neve/assets/js/build/modern/scroll-to-top.js?ver=4.2.2" id="neve-scroll-to-top-js" async></script> <script id="wp-emoji-settings" type="application/json"> {"baseUrl":"https://s.w.org/images/core/emoji/17.0.2/72x72/","ext":".png","svgUrl":"https://s.w.org/images/core/emoji/17.0.2/svg/","svgExt":".svg","source":{"concatemoji":"https://spellingmatters.blog/wp-includes/js/wp-emoji-release.min.js?ver=6.9.4"}} </script> <script type="module"> /*! This file is auto-generated */ const a=JSON.parse(document.getElementById("wp-emoji-settings").textContent),o=(window._wpemojiSettings=a,"wpEmojiSettingsSupports"),s=["flag","emoji"];function i(e){try{var t={supportTests:e,timestamp:(new Date).valueOf()};sessionStorage.setItem(o,JSON.stringify(t))}catch(e){}}function c(e,t,n){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);t=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(n,0,0);const a=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);return t.every((e,t)=>e===a[t])}function p(e,t){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);var n=e.getImageData(16,16,1,1);for(let e=0;e<n.data.length;e++)if(0!==n.data[e])return!1;return!0}function u(e,t,n,a){switch(t){case"flag":return n(e,"\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f","\ud83c\udff3\ufe0f\u200b\u26a7\ufe0f")?!1:!n(e,"\ud83c\udde8\ud83c\uddf6","\ud83c\udde8\u200b\ud83c\uddf6")&&!n(e,"\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f","\ud83c\udff4\u200b\udb40\udc67\u200b\udb40\udc62\u200b\udb40\udc65\u200b\udb40\udc6e\u200b\udb40\udc67\u200b\udb40\udc7f");case"emoji":return!a(e,"\ud83e\u1fac8")}return!1}function f(e,t,n,a){let r;const o=(r="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?new OffscreenCanvas(300,150):document.createElement("canvas")).getContext("2d",{willReadFrequently:!0}),s=(o.textBaseline="top",o.font="600 32px Arial",{});return e.forEach(e=>{s[e]=t(o,e,n,a)}),s}function r(e){var t=document.createElement("script");t.src=e,t.defer=!0,document.head.appendChild(t)}a.supports={everything:!0,everythingExceptFlag:!0},new Promise(t=>{let n=function(){try{var e=JSON.parse(sessionStorage.getItem(o));if("object"==typeof e&&"number"==typeof e.timestamp&&(new Date).valueOf()<e.timestamp+604800&&"object"==typeof e.supportTests)return e.supportTests}catch(e){}return null}();if(!n){if("undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas&&"undefined"!=typeof URL&&URL.createObjectURL&&"undefined"!=typeof Blob)try{var e="postMessage("+f.toString()+"("+[JSON.stringify(s),u.toString(),c.toString(),p.toString()].join(",")+"));",a=new Blob([e],{type:"text/javascript"});const r=new Worker(URL.createObjectURL(a),{name:"wpTestEmojiSupports"});return void(r.onmessage=e=>{i(n=e.data),r.terminate(),t(n)})}catch(e){}i(n=f(s,u,c,p))}t(n)}).then(e=>{for(const n in e)a.supports[n]=e[n],a.supports.everything=a.supports.everything&&a.supports[n],"flag"!==n&&(a.supports.everythingExceptFlag=a.supports.everythingExceptFlag&&a.supports[n]);var t;a.supports.everythingExceptFlag=a.supports.everythingExceptFlag&&!a.supports.flag,a.supports.everything||((t=a.source||{}).concatemoji?r(t.concatemoji):t.wpemoji&&t.twemoji&&(r(t.twemoji),r(t.wpemoji)))}); //# sourceURL=https://spellingmatters.blog/wp-includes/js/wp-emoji-loader.min.js </script> </body> </html>