UNPKG

generator-ramp-webextension-kickstart

Version:
626 lines (565 loc) 17.9 kB
const chalk = require('chalk') const Generator = require('yeoman-generator') const path = require('path') const slugify = require('slugify') const yosay = require('yosay') module.exports = class extends Generator { constructor (...args) { super(...args) // load package this.pkg = require('../package.json') // set source root path to templates this.sourceRoot(path.join(__dirname, 'templates')) // init extension manifest data this.manifest = { permissions: {} } } prompting () { const prompts = [{ type: 'input', name: 'name', message: 'What would you like to call this extension?', default: this.appname }, { type: 'input', name: 'shortName', message: 'And how would you call it if you only had 12 characters (short_name)?', default: answers => answers.name.substr(0, 11).trim() }, { name: 'description', message: 'How would you like to describe this extension?', default: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.' }, { type: 'list', name: 'action', message: 'Would you like to use UI Action?', choices: [ 'No', 'Browser', 'Page' ] }, { type: 'list', name: 'overridePage', message: 'Would you like to override a chrome page?', choices: [ 'No', 'Bookmarks Page', 'History Page', 'Newtab Page' ] }, { type: 'checkbox', name: 'uifeatures', message: 'Would you like more UI Features?', choices: [{ value: 'options', name: 'Options Page', checked: false }, { value: 'devtoolsPage', name: 'Devtools Page', checked: false }, { value: 'contentscript', name: 'Content Scripts', checked: false }, { value: 'omnibox', name: 'Omnibox', checked: false }] }, { type: 'checkbox', name: 'permissions', message: 'Would you like to use permissions?', choices: [{ value: 'bookmarks', name: 'Bookmarks', checked: false }, { value: 'browsingData ', name: 'BrowsingData ', checked: false }, { value: 'clipboardRead', name: 'ClipboardRead', checked: false }, { value: 'clipboardWrite', name: 'ClipboardWrite', checked: false }, { value: 'contentSettings', name: 'ContentSettings', checked: false }, { value: 'contextMenus', name: 'ContextMenus', checked: false }, { value: 'cookies', name: 'Cookies', checked: false }, { value: 'commands', name: 'Commands', checked: false }, { value: 'debugger', name: 'Debugger', checked: false }, { value: 'declarativeContent', name: 'DeclarativeContent', checked: false }, { value: 'history', name: 'History', checked: false }, { value: 'input', name: 'Input', checked: false }, { value: 'management', name: 'Management', checked: false }, { value: 'notifications', name: 'Notifications', checked: false }, { value: 'pageCapture', name: 'PageCapture', checked: false }, { value: 'proxy', name: 'Proxy', checked: false }, { value: 'tabs', name: 'Tabs', checked: false }, { value: 'tabCapture', name: 'TabCapture', checked: false }, { value: 'topSites', name: 'TopSites', checked: false }, { value: 'webNavigation', name: 'WebNavigation', checked: false }, { value: 'webRequest', name: 'WebRequest', checked: false }, { value: 'webRequestBlocking', name: 'WebRequestBlocking', checked: false }] }, { type: 'confirm', name: 'promo', default: false, message: 'Would you like to install promo images for the Chrome Web Store?' }] return this.prompt(prompts).then(function (answers) { const isChecked = (choices, value) => choices.indexOf(value) > -1 // Meta this.appname = this.manifest.name = answers.name.replace(/"/g, '\\"') this.appShortName = this.manifest.shortName = answers.shortName.replace(/"/g, '\\"') this.appDescription = answers.description this.manifest.description = answers.description.replace(/"/g, '\\"') // UI Actions this.manifest.action = (answers.action === 'No') ? 0 : (answers.action === 'Browser') ? 1 : 2 // UI Features this.manifest.options = isChecked(answers.uifeatures, 'options') this.manifest.devtoolsPage = isChecked(answers.uifeatures, 'devtoolsPage') this.manifest.omnibox = isChecked(answers.uifeatures, 'omnibox') this.manifest.contentscript = isChecked(answers.uifeatures, 'contentscript') // Permissions this.manifest.permissions.bookmarks = isChecked(answers.permissions, 'bookmarks') this.manifest.permissions.browsingData = isChecked(answers.permissions, 'browsingData') this.manifest.permissions.clipboardRead = isChecked(answers.permissions, 'clipboardRead') this.manifest.permissions.clipboardWrite = isChecked(answers.permissions, 'clipboardWrite') this.manifest.permissions.commands = isChecked(answers.permissions, 'commands') this.manifest.permissions.contentSettings = isChecked(answers.permissions, 'contentSettings') this.manifest.permissions.contextMenus = isChecked(answers.permissions, 'contextMenus') this.manifest.permissions.cookies = isChecked(answers.permissions, 'cookies') this.manifest.permissions.debugger = isChecked(answers.permissions, 'debugger') this.manifest.permissions.declarativeContent = isChecked(answers.permissions, 'declarativeContent') this.manifest.permissions.history = isChecked(answers.permissions, 'history') this.manifest.permissions.input = isChecked(answers.permissions, 'input') this.manifest.permissions.management = isChecked(answers.permissions, 'management') this.manifest.permissions.notifications = isChecked(answers.permissions, 'notifications') this.manifest.permissions.pageCapture = isChecked(answers.permissions, 'pageCapture') this.manifest.permissions.proxy = isChecked(answers.permissions, 'proxy') this.manifest.permissions.tabCapture = isChecked(answers.permissions, 'tabCapture') this.manifest.permissions.tabs = isChecked(answers.permissions, 'tabs') this.manifest.permissions.topSites = isChecked(answers.permissions, 'topSites') this.manifest.permissions.webNavigation = isChecked(answers.permissions, 'webNavigation') this.manifest.permissions.webRequest = isChecked(answers.permissions, 'webRequest') this.manifest.permissions.webRequestBlocking = isChecked(answers.permissions, 'webRequestBlocking') // Override a chrome page switch (answers.overridePage) { case 'Bookmarks Page': this.manifest.overridePage = true this.manifest.bookmarksPage = true break case 'History Page': this.manifest.overridePage = true this.manifest.historyPage = true break case 'Newtab Page': this.manifest.overridePage = true this.manifest.newtabPage = true break case 'No': this.manifest.overridePage = false break } // Promo images this.promo = answers.promo }.bind(this)) } tasks () { this.fs.copy( this.templatePath('gulpfile.babel.js'), this.destinationPath('gulpfile.babel.js') ) this.fs.copy( this.templatePath('tasks/**/*'), this.destinationPath('tasks') ) } packageJSON () { this.fs.copyTpl( this.templatePath('_package.json'), this.destinationPath('package.json'), { name: slugify(this.appname), description: this.manifest.description } ) } readme () { this.fs.copyTpl( this.templatePath('README.md'), this.destinationPath('README.md'), { name: this.appname, description: this.appDescription } ) } git () { this.fs.copy( this.templatePath('gitignore'), this.destinationPath('.gitignore') ) this.fs.copy( this.templatePath('gitattributes'), this.destinationPath('.gitattributes') ) } babelrc () { this.fs.copy( this.templatePath('babelrc'), this.destinationPath('.babelrc') ) } promo () { if (!this.promo) { return } this.fs.copy( this.templatePath('babelrc'), this.destinationPath('.babelrc') ) this.fs.copy( this.templatePath('promo/Chrome-Webstore-Icon_128x128.png'), this.destinationPath('promo/Chrome-Webstore-Icon_128x128.png') ) this.fs.copy( this.templatePath('promo/Promo-Image-Large_920x680.png'), this.destinationPath('promo/Promo-Image-Large_920x680.png') ) this.fs.copy( this.templatePath('promo/Promo-Image-Marquee_1400x560.png'), this.destinationPath('promo/Promo-Image-Marquee_1400x560.png') ) this.fs.copy( this.templatePath('promo/Promo-Image-Small_440x280.png'), this.destinationPath('promo/Promo-Image-Small_440x280.png') ) this.fs.copy( this.templatePath('promo/Screenshot_1280x800.png'), this.destinationPath('promo/Screenshot_1280x800.png') ) this.fs.copy( this.templatePath('promo/Screenshot_640x400.png'), this.destinationPath('promo/Screenshot_640x400.png') ) } editorConfig () { this.fs.copy( this.templatePath('editorconfig'), this.destinationPath('.editorconfig') ) } manifest () { var manifest = {} var permissions = [] var items = [] function buildJSONPart (part) { return JSON.stringify(part, null, 2).replace(/\n/g, '\n ') } // add browser / page action field if (this.manifest.action > 0) { var action = { default_icon: { 19: 'images/icon-19.png', 38: 'images/icon-38.png' }, default_title: '__MSG_browserActionTitle__', default_popup: 'pages/popup.html' } var title = (this.manifest.action === 1) ? 'browser_action' : 'page_action' manifest[title] = buildJSONPart(action) } // add options page field. if (this.manifest.options) { manifest.options_page = '"pages/options.html"' manifest.options_ui = buildJSONPart({ 'page': 'pages/options.html', 'chrome_style': true }) } // add devtool page field. if (this.manifest.devtoolsPage) { manifest.minimum_chrome_version = '"10.0"' manifest.devtools_page = '"pages/devtools.html"' } // Override Pages if (this.manifest.overridePage) { // add history page field. if (this.manifest.historyPage) { manifest.chrome_url_overrides = buildJSONPart({ history: 'pages/history.html' }) } // add bookmarks page field. if (this.manifest.bookmarksPage) { manifest.chrome_url_overrides = buildJSONPart({ bookmarks: 'pages/bookmarks.html' }) } // add newtab page field. if (this.manifest.newtabPage) { manifest.chrome_url_overrides = buildJSONPart({ newtab: 'pages/newtab.html' }) } } // add omnibox keyword field. if (this.manifest.omnibox) { manifest.omnibox = buildJSONPart({ keyword: this.manifest.shortName }) } // add contentscript field. if (this.manifest.contentscript) { const contentscript = [{ matches: ['http://*/*', 'https://*/*'], css: ['styles/contentscript.css'], js: ['scripts/contentscript.js'], run_at: 'document_end', all_frames: false }] manifest.content_scripts = buildJSONPart(contentscript) } // add generate permission field. for (let p in this.manifest.permissions) { if (this.manifest.permissions[p]) { permissions.push(p) } } // add generic match pattern field. if (this.manifest.permissions.tabs) { permissions.push('<all_urls>') } // add permissions if (permissions.length > 0) { manifest.permissions = buildJSONPart(permissions) } for (let i in manifest) { items.push([' "', i, '": ', manifest[i]].join('')) } this.manifest.items = (items.length > 0) ? ',\n' + items.join(',\n') : '' this.fs.copyTpl( this.templatePath('app/manifest.json'), this.destinationPath('app/manifest.json'), { items: this.manifest.items } ) } actions () { if (this.manifest.action === 0) return this.fs.copy( this.templatePath('app/pages/popup.html'), this.destinationPath('app/pages/popup.html') ) this.fs.copy( this.templatePath('app/scripts/popup.js'), this.destinationPath('app/scripts/popup.js') ) this.fs.copy( this.templatePath('app/styles/popup.scss'), this.destinationPath('app/styles/popup.scss') ) this.fs.copy( this.templatePath('app/images/icon-19.png'), this.destinationPath('app/images/icon-19.png') ) this.fs.copy( this.templatePath('app/images/icon-38.png'), this.destinationPath('app/images/icon-38.png') ) } backgroundpage () { let filename = 'background.js' if (this.manifest.action === 2) { filename = 'background.pageaction.js' } else if (this.manifest.action === 1) { filename = 'background.browseraction.js' } this.fs.copy( this.templatePath(`app/scripts/${filename}`), this.destinationPath('app/scripts/background.js') ) } options () { if (!this.manifest.options) return this.fs.copy( this.templatePath('app/pages/options.html'), this.destinationPath('app/pages/options.html') ) this.fs.copy( this.templatePath('app/scripts/options.js'), this.destinationPath('app/scripts/options.js') ) this.fs.copy( this.templatePath('app/styles/options.scss'), this.destinationPath('app/styles/options.scss') ) } devtools () { if (!this.manifest.devtoolsPage) return this.fs.copy( this.templatePath('app/pages/devtools.html'), this.destinationPath('app/pages/devtools.html') ) this.fs.copy( this.templatePath('app/scripts/devtools.js'), this.destinationPath('app/scripts/devtools.js') ) this.fs.copy( this.templatePath('app/styles/devtools.scss'), this.destinationPath('app/styles/devtools.scss') ) } history () { if (!this.manifest.historyPage) return this.fs.copy( this.templatePath('app/pages/history.html'), this.destinationPath('app/pages/history.html') ) this.fs.copy( this.templatePath('app/scripts/history.js'), this.destinationPath('app/scripts/history.js') ) this.fs.copy( this.templatePath('app/styles/history.scss'), this.destinationPath('app/styles/history.scss') ) } bookmarks () { if (!this.manifest.bookmarksPage) return this.fs.copy( this.templatePath('app/pages/bookmarks.html'), this.destinationPath('app/pages/bookmarks.html') ) this.fs.copy( this.templatePath('app/scripts/bookmarks.js'), this.destinationPath('app/scripts/bookmarks.js') ) this.fs.copy( this.templatePath('app/styles/bookmarks.scss'), this.destinationPath('app/styles/bookmarks.scss') ) } newtab () { if (!this.manifest.newtabPage) return this.fs.copy( this.templatePath('app/pages/newtab.html'), this.destinationPath('app/pages/newtab.html') ) this.fs.copy( this.templatePath('app/scripts/newtab.js'), this.destinationPath('app/scripts/newtab.js') ) this.fs.copy( this.templatePath('app/styles/newtab.scss'), this.destinationPath('app/styles/newtab.scss') ) } contentscript () { if (!this.manifest.contentscript) return this.fs.copy( this.templatePath('app/scripts/contentscript.js'), this.destinationPath('app/scripts/contentscript.js') ) this.fs.copy( this.templatePath('app/styles/contentscript.scss'), this.destinationPath('app/styles/contentscript.scss') ) } locales () { this.fs.copyTpl( this.templatePath('app/_locales/en/messages.json'), this.destinationPath('app/_locales/en/messages.json'), { name: this.manifest.name, shortName: this.manifest.shortName, description: this.manifest.description, action: this.manifest.action } ) } assets () { this.fs.copy( this.templatePath('app/images/icon-16.png'), this.destinationPath('app/images/icon-16.png') ) this.fs.copy( this.templatePath('app/images/icon-128.png'), this.destinationPath('app/images/icon-128.png') ) this.fs.copy( this.templatePath('app/fonts/gitkeep'), this.destinationPath('app/fonts/.gitkeep') ) } installing () { this.log('I\'m all done. Running ' + chalk.yellow('npm install') + ' for you to install the required dependencies. If this fails, try running the command yourself.') this.npmInstall() } end () { this.log( yosay('Please run ' + chalk.red('gulp') + ' or ' + chalk.yellow('gulp --watch') + ' and load the generated dist into chrome.') ) } }