Christopher Bloom
Photo by Jonas Denil on Unsplash
Photo by Fancycrave on Unsplash
// core/misc/drupal.init.es6.js
(function(domready, Drupal, drupalSettings) {
// Attach all behaviors.
domready(() => {
Drupal.attachBehaviors(document, drupalSettings);
});
})(domready, Drupal, window.drupalSettings);
// core/misc/drupal.es6.js
Drupal.attachBehaviors = function(context, settings) {
context = context || document;
settings = settings || drupalSettings;
const behaviors = Drupal.behaviors;
// Execute all of them.
Object.keys(behaviors || {}).forEach(i => {
if (typeof behaviors[i].attach === 'function') {
// Don't stop the execution of behaviors in case of an error.
try {
behaviors[i].attach(context, settings);
} catch (e) {
Drupal.throwError(e);
}
}
});
};
(function moduleNameClosure(local, alias, for, those, window, D) {
// We're safe in here ...
}(things, that, live, on, window, Drupal));
(function moduleNameClosure(D) {
D.behaviors.p2UniqueNamespace = {
attach: function drupalAttach() {
// Do stuff ...
},
};
}(Drupal));
Object.keys(Drupal.behaviors).find(b => b === 'myNamespace')
? 'DANGER! NAMESPACE EXISTS!'
: 'Your namespace is safe';
(function moduleNameClosure(D) {
D.behaviors.p2UniqueNamespace = {
attach: function drupalAttach(context) {
$('.thing', context)
.once('p2UniqueNamespace')
.addClass('flerp');
},
};
}(Drupal));
(function moduleNameClosure(D, $) {
D.behaviors.p2UniqueNamespace = {
attach() { // Enhanced object literals shorthand functions
$('.thing')
.on('click', () => doStuff()); // Arrow. Warning: scope
}, // Trailing comma = good
}; // semicolon
}(Drupal, jQuery));
(function moduleNameClosure(D, $) {
D.behaviors.p2UniqueNamespace = {
attach(context) { // "$" convention for jQuery element
$('.flerp', context).doAwesome();
// OR
$(context).find('.flerp').doAwesome();
},
};
}(Drupal, jQuery));
(function moduleNameClosure(D, $) {
D.behaviors.p2UniqueNamespace = {
attach(context, settings) {
const { bloomModule } = settings; // Destructuring
$('.flerp', context)
.doAwesome(bloomModule.awesomeLevel);
},
};
}(Drupal, jQuery));
function bloom_preprocess_html(&$vars) {
$vars['#attached']['drupalSettings']['bloomModule']['awesomeLevel'] = 'RAD';
}
(function moduleNameClosure(D, $) {
D.behaviors.p2UniqueNamespace = {
attach(context, settings) {
const { bloomModule } = settings;
const $flerp = $('.flerp', context); // Var your jQuery
// No settings or no DOM, GET OUT
if (!bloomModule || !$flerp.length) {
return;
}
$flerp.doAwesome(bloomModule.awesomeLevel);
},
};
}(Drupal, jQuery));
(function moduleNameClosure(D, $) {
D.behaviors.p2UniqueNamespace = {
attach(context, settings) {
const $header = $('.header', context);
const $menu = $header.find('.menu'); // scoped to $header
const $trigger = $menu.find('.trigger'); // scoped to $header $menu
// Single event bubbles up for many href elements
$header.on('click', 'a', function headerClick(e) {
$(e.delegateTarget).css('border', 'red'); // $header
$(this).css('color', 'blue'); // this = <a>
});
$trigger.on('click', () => $menu.toggle());
},
};
}(Drupal, jQuery));
(function moduleNameClosure(D, $) {
D.behaviors.p2UniqueNamespace = {
attach(context, settings) {
const $header = $('.header', context);
// "this" is VERY important to click()
$header.on('click', 'a', function headerClick() {
$(this).css('color', 'blue'); // this = <a>
});
// Just need to execute something, scope doesn't matter
$trigger.on('click', () => $menu.toggle());
},
};
}(Drupal, jQuery));
(function moduleNameClosure(D, $) {
// Helper function
function findAllTheThings(collection) {
return collection
.filter(({ name }) => name === 'Bill Murray')
.map(person => {
person.awesome = person.awesome * 10;
return person;
})
}
D.behaviors.p2UniqueNamespace = {
attach(context, settings) {
const { people } = settings;
if (!people) {
return;
}
$peopleDivs = findAllTheThings(settings.people)
.map(person => $(<div/>).text(person));
$('.people-holder', context).append($peopleDivs);
},
};
}(Drupal, jQuery));
// utils.js
(function utilsClosure(global) {
const onlyAwesome = collection =>
collection.filter(({ name }) => name === 'Bill Murray');
global.bloomUtils = {
onlyAwesome, // Enhanced object literals shorthand props!
};
}(window));
// bloom-module.js
(function moduleNameClosure(D, $, u) {
D.behaviors.p2UniqueNamespace = {
attach(context, settings) {
const { people } = settings;
if (!people) { return; }
$peopleDivs = u.onlyAwesome(people)
.map(person => $(<div/>).text(person));
$('.people-holder', context).append($peopleDivs);
},
};
}(Drupal, jQuery, bloomUtils));
(function moduleNameClosure(D, $) {
const state = {
menuOpen: true,
};
D.behaviors.p2UniqueNamespace = {
attach(context, settings) {
const state2Dom = (context, state) => {
$('.menu', context).toggleClass('open', state.menuOpen);
};
$('.toggle', context)
.on('click', () => state.menu = !state.menu);
state2Dom();
},
};
}(Drupal, jQuery));
(function moduleNameClosure(D, _) {
D.behaviors.p2UniqueNamespace = {
attach(context, settings) {
// get() is safe object querying
const thing =
_.get(settings, 'bloomModule.some.thing', 'default');
// assign() (available in ES6) cascades overrides of object
const defaults = { color: blue };
const carouselSettings =
_.assign({}, defaults, settings.carousel);
const days = _.range(1, 5).map(day => getResults(day));
$(window)
.on('resize', _.debounce(() => console.log('blerp')), 400));
},
};
}(Drupal, _));
(function moduleNameClosure(D) {
D.behaviors.p2UniqueNamespace = {
attach(context, settings) {
// Gross
let loop = 0;
const peopleArray = [];
for (loop; loop < settings.people.length; loop++) {
const person = settings.people[loop];
person.fullName = `${person.firstName} ${person.lastName}`;
peopleArray.push(person);
}
// Awww yisss
const betterArray = settings.people.map(person => ({
...person,
{ fullname: `${person.firstName} ${person.lastName}` },
}));
},
};
}(Drupal));
(function moduleNameClosure(D) {
D.behaviors.p2UniqueNamespace = {
attach(context, settings) {
const { murrayQuotesUri } = settings.p2;
const $widget = $('.widget', context);
if (!murrayQuotesUri || !$widget.length) { return; }
fetch(murrayQuotesUri)
.then(data => data.json())
.then(quotes => quotes.map(quote => $('<div/>').text(quote)))
.then($quotes => $widget.append($quotes));
},
};
}(Drupal))
// rando-module/js/rando-module.js
(function randoModuleClosure(D, $, u) {
D.behaviors.randoModule = {
attach(context, settings) {
// Other modules subscribe to the promise
u.quotes
.then(qs => qs.map(q => $("<div/>".text(q))))
.then($qsEl => $(".w", context).append($qsEl));
},
};
})(Drupal, jQuery, p2Utils);
If multiple behaviors share logic, move the logic to a dependent library
# p2-utils/p2-utils.libraries.yml
core:
js: js/utils.js
dependencies:
- core/drupal
- core/drupalSettings
// p2-utils/js/utils.js
(function utilsGlobalClosure(global) {
global.p2Utils = {
init(uri) {
this.quotes = fetch(uri)
.then(data => data.json());
}
};
})(window);
(function utilsModuleClosure(D, $, u) {
D.behaviors.p2Utils = {
attach(context, settings) {
const { murrayUri } = settings.p2;
if (murrayUri) {
u.init(murrayUri); // Util calls API
}
}
};
})(Drupal, jQuery, p2Utils);
# rando-module/rando-module.libraries.yml
core:
js: js/rando-module.js
dependencies:
- p2-utils/core
- core/drupal
- core/drupalSettings
// Mistaken that all functions had to be behaviors
Drupal.behaviors.randomFunction = function() { }
// Didn't understand settings arg
Drupal.behaviors.nameSpace = {
attach: function(context, settings) {
const mySetting = Drupal.settings.mySetting;
}
};
// Non-strict equality
var thing == 'something';
// .attach() already runs on $(document).ready()
$(document).ready(function() {});
// Stop using 'use strict'
'use strict';
Photo by Jeremy Thomas on Unsplash