Refactor extension to webpack
This change is the biggest in the history of the project. The entire
project has been refactored so it is built with webpack.
This involves:
- Creating webpack and npm config files.
- Fixing some bugs in the code due to the fact that webpack uses strict
mode.
- Merging some pieces of code which were shared throughout the codebase
(not exhaustive, more work should be done in this direction).
- Splitting the console_inject.js file into separate files (it had 1000+
lines).
- Adapting all the build-related files (Makefile, bash scripts, etc.)
- Changing the docs to explain the new build process.
- Changing the Zuul playbook/roles to adapt to the new build process.
Change-Id: I16476d47825461c3a318b3f1a1eddb06b2df2e89
diff --git a/src/contentScripts/communityConsole/batchLock.js b/src/contentScripts/communityConsole/batchLock.js
new file mode 100644
index 0000000..5bc0361
--- /dev/null
+++ b/src/contentScripts/communityConsole/batchLock.js
@@ -0,0 +1,133 @@
+import {removeChildNodes, createExtBadge} from './utils.js';
+
+export function nodeIsReadToggleBtn(node) {
+ return ('tagName' in node) && node.tagName == 'MATERIAL-BUTTON' &&
+ node.getAttribute('debugid') !== null &&
+ (node.getAttribute('debugid') == 'mark-read-button' ||
+ node.getAttribute('debugid') == 'mark-unread-button') &&
+ ('parentNode' in node) && node.parentNode !== null &&
+ ('parentNode' in node.parentNode) &&
+ node.parentNode.querySelector('[debugid="batchlock"]') === null &&
+ node.parentNode.parentNode !== null &&
+ ('tagName' in node.parentNode.parentNode) &&
+ node.parentNode.parentNode.tagName == 'EC-BULK-ACTIONS';
+}
+
+export function addBatchLockBtn(readToggle) {
+ var clone = readToggle.cloneNode(true);
+ clone.setAttribute('debugid', 'batchlock');
+ clone.classList.add('TWPT-btn--with-badge');
+ clone.setAttribute('title', chrome.i18n.getMessage('inject_lockbtn'));
+ clone.querySelector('material-icon').setAttribute('icon', 'lock');
+ clone.querySelector('i.material-icon-i').textContent = 'lock';
+
+ var badge = createExtBadge();
+ clone.append(badge);
+
+ clone.addEventListener('click', function() {
+ var modal = document.querySelector('.pane[pane-id="default-1"]');
+
+ var dialog = document.createElement('material-dialog');
+ dialog.setAttribute('role', 'dialog');
+ dialog.setAttribute('aria-modal', 'true');
+ dialog.classList.add('TWPT-dialog');
+
+ var header = document.createElement('header');
+ header.setAttribute('role', 'presentation');
+ header.classList.add('TWPT-dialog-header');
+
+ var title = document.createElement('div');
+ title.classList.add('TWPT-dialog-header--title', 'title');
+ title.textContent = chrome.i18n.getMessage('inject_lockbtn');
+
+ header.append(title);
+
+ var main = document.createElement('main');
+ main.setAttribute('role', 'presentation');
+ main.classList.add('TWPT-dialog-main');
+
+ var p = document.createElement('p');
+ p.textContent = chrome.i18n.getMessage('inject_lockdialog_desc');
+
+ main.append(p);
+
+ dialog.append(header, main);
+
+ var footers = [['lock', 'unlock', 'cancel'], ['reload', 'close']];
+
+ for (var i = 0; i < footers.length; ++i) {
+ var footer = document.createElement('footer');
+ footer.setAttribute('role', 'presentation');
+ footer.classList.add('TWPT-dialog-footer');
+ footer.setAttribute('data-footer-id', i);
+
+ if (i > 0) footer.classList.add('is-hidden');
+
+ footers[i].forEach(action => {
+ var btn = document.createElement('material-button');
+ btn.setAttribute('role', 'button');
+ btn.classList.add('TWPT-dialog-footer-btn');
+ if (i == 1) btn.classList.add('is-disabled');
+
+ switch (action) {
+ case 'lock':
+ case 'unlock':
+ btn.addEventListener('click', _ => {
+ if (btn.classList.contains('is-disabled')) return;
+ var message = {
+ action,
+ prefix: 'TWPT-batchlock',
+ };
+ window.postMessage(message, '*');
+ });
+ break;
+
+ case 'cancel':
+ case 'close':
+ btn.addEventListener('click', _ => {
+ if (btn.classList.contains('is-disabled')) return;
+ modal.classList.remove('visible');
+ modal.style.display = 'none';
+ removeChildNodes(modal);
+ });
+ break;
+
+ case 'reload':
+ btn.addEventListener('click', _ => {
+ if (btn.classList.contains('is-disabled')) return;
+ window.location.reload()
+ });
+ break;
+ }
+
+ var content = document.createElement('div');
+ content.classList.add('content', 'TWPT-dialog-footer-btn--content');
+ content.textContent =
+ chrome.i18n.getMessage('inject_lockdialog_btn_' + action);
+
+ btn.append(content);
+ footer.append(btn);
+ });
+
+ var clear = document.createElement('div');
+ clear.style.clear = 'both';
+
+ footer.append(clear);
+ dialog.append(footer);
+ }
+
+ removeChildNodes(modal);
+ modal.append(dialog);
+ modal.classList.add('visible', 'modal');
+ modal.style.display = 'flex';
+ });
+
+ var duplicateBtn =
+ readToggle.parentNode.querySelector('[debugid="mark-duplicate-button"]');
+ if (duplicateBtn)
+ duplicateBtn.parentNode.insertBefore(
+ clone, (duplicateBtn.nextSibling || duplicateBtn));
+ else
+ readToggle.parentNode.insertBefore(
+ clone, (readToggle.nextSibling || readToggle));
+}