') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); GitHub - maxpoletaev/node-beml: HTML preprocessor for BEM · GitHub
Skip to content

Repository files navigation

BEML Build Status

This is simple HTML preprocessor (or postprocessor) which extend HTML syntax for comfortable working with bem html.

Also available plugins for Gulp, Grunt, Broccoli and Postxml.

Why?

Raw HTML in BEM style is difficult to read. Also, I (and not only I) love HTML and don't want to use BEMHTML, BEMJSON and others specific technologies.

Targets

  • Maximum simplicity - HTML syntax, without translate from another language.
  • Possibility port to other languages (e.g. PHP or Python).
  • Joint work with template engines.
  • Ease of use.

Sample

<divblock="b-animals"><divelem="cat" mod="size:big, color:red"></div></div>

translated to

<divclass="b-animals"><divclass="b-animals__cat b-animals__cat_size_big b-animals__cat_color_red"></div></div>

How to use

varbeml=require('beml');varconfig={elemPrefix: '__',modPrefix: '_',modDlmtr: '_'};varhtml=beml('<div block="b-block" mod="size:big"></div>',config);console.log(html);

Syntax reference

Blocks

<divblock="animals"><divblock="unicorn"></div></div>
<divclass="animals"><divclass="unicorn"></div></div>

Elements

<divblock="animals"><divelem="item"><divelem="item-name"></div></div></div>
<divclass="animals"><divclass="animals__item"><divclass="animals__item-name"></div></div></div>

Modifiers

<divblock="animals"><divblock="unicorn" mod="size:large, female"></div></div>
<divclass="animals"><divclass="unicorn inicorn_size_large unicorn_female"></div></div>

Mixes

<divblock="animals"><divelem="item" mix="block:unicorn, mod: [large, female]"><divblock="unicorn" elem="photo"></div><divelem="item-name"></div></div></div>
<divclass="animals"><divclass="animals__item unicorn unicorn_large unicorn_female"><divclass="unicorn__photo"></div><divclass="animals__item-name"></div></div></div>

For complex values you can use pseudo JSON syntax:

<divblock="unicorn" mix="block:animals, elem:item, mod:{size:large,gender:female}"></div><divblock="unicorn" mix="{block:b-mix-1}, {block:b-mix-2, mod:[mod1, mod2]}"></div>
<divclass="unicorn animals__item animals__item_size_large animals__item_gender_female"></div><divclass="unicorn b-mix-1 b-mix-2 b-mix-2_mod1 b-mix-2_mod_2"></div>

About

HTML preprocessor for BEM

Resources

Stars

64 stars

Watchers

7 watching

Forks

Releases

Packages

Used by

Contributors

Languages