From 2d6d884eafe9c24eada3cadac49e331dd32d0b22 Mon Sep 17 00:00:00 2001 From: David Ascher Date: Thu, 23 Jan 2014 13:42:19 -0800 Subject: [PATCH] template, prompt working (needs fixes) --- .gitignore | 59 ++++++++++++++++ Gruntfile.js | 134 +++++++++++++++++++++++++++++++++++++ package.json | 33 +++++++++ template/.gitignore | 59 ++++++++++++++++ template/.travis.yml | 6 ++ template/component.css | 34 ++++++++++ template/component.html | 91 +++++++++++++++++++++++++ template/locale/en-US.json | 14 ++++ thumbnail.png | Bin 0 -> 13652 bytes 9 files changed, 430 insertions(+) create mode 100644 .gitignore create mode 100644 Gruntfile.js create mode 100644 package.json create mode 100644 template/.gitignore create mode 100755 template/.travis.yml create mode 100644 template/component.css create mode 100644 template/component.html create mode 100644 template/locale/en-US.json create mode 100644 thumbnail.png diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..074e4e8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,59 @@ +# Compiled source # +################### +*.com +*.class +*.dll +*.exe +*.o +*.so + +# Packages # +############ +# it's better to unpack these files and commit the raw source +# git has its own built in compression methods +*.7z +*.dmg +*.gz +*.iso +*.jar +*.rar +*.tar +*.zip + +# Logs and databases # +###################### +*.log +*.sql +*.sqlite + +# OS generated files # +###################### +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Node-specific stuff # +####################### + +lib-cov +lcov.info +*.seed +*.log +*.csv +*.dat +*.out +*.pid +*.gz + +pids +logs +results +build +.grunt + +node_modules + diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000..1f36862 --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,134 @@ +// use as: grunt serve to serve the component for the designer +// TBD: bring back linting, jshint, etc. + +module.exports = function(grunt) { + var path = require('path'); + // Project configuration. + var defaultName = path.basename(process.cwd()); + if (defaultName.indexOf('component-') == 0) { + defaultName = defaultName.slice('component-'.length, defaultName.length); + } + grunt.initConfig({ + prompt: { + target: { + options: { + questions: [ + { + config: 'template.component.options.data.name', // arbitray name or config for any other grunt task + type: 'input', // list, checkbox, confirm, input, password + message: 'Component name', + default: defaultName, // default value if nothing is entered + } + ] + } + } + }, + template: { + 'component': { + 'files': { + 'component.html': ['template/component.html'], + 'component.css': ['template/component.css'], + 'locale/en-US.json': ['template/locale/en-US.json'], + } + } + }, + pkg: grunt.file.readJSON('package.json'), + csslint: { + lax: { + options: { + "adjoining-classes": false, + "box-model": false, + "box-sizing": false, + "bulletproof-font-face": false, + "compatible-vendor-prefixes": false, + "ids": false, + "important": false, + "outline-none": false, + "overqualified-elements": false, + "qualified-headings": false, + "regex-selectors": false, + "star-property-hack": false, + "underscore-property-hack": false, + "universal-selector": false, + "unique-headings": false, + "unqualified-attributes": false, + "vendor-prefix": false, + "zero-units": false, + "fallback-colors": false + }, + src: [ + "**/*.css", + '!node_modules/**' + ] + }, + }, + jshint: { + options: { + "-W054": true, // The Function constructor is a form of eval + "-W069": true // thing["property"] is better written in dot notation + }, + files: [ + "Gruntfile.js", + "**/*.js", + '!node_modules/**' + ] + }, + inlinelint: { + html: ['**/*.html', + '!node_modules/**' + ] + }, + connect: { + server: { + options: { + port: 9001, + base: __dirname, + keepalive: true, + open: 9001, + middleware: function(connect, options) { + var middlewares = []; + if (!Array.isArray(options.base)) { + options.base = [options.base]; + } + var directory = options.directory || options.base[options.base.length - 1]; + middlewares.push(function(req, res, next) { + // we need to setup CORS headers so that the designer can load the component + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS'); + res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); + next(); + }); + options.base.forEach(function(base) { + // Serve static files. + middlewares.push(connect.static(base)); + }); + return middlewares; + }, + } + } + }, + }); + + grunt.loadNpmTasks( "grunt-contrib-csslint" ); + grunt.loadNpmTasks( "grunt-contrib-jshint" ); + grunt.loadNpmTasks('grunt-lint-inline'); + grunt.loadNpmTasks('grunt-contrib-connect'); + grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-prompt'); + grunt.loadNpmTasks('grunt-template'); + + grunt.registerTask('customize', ['prompt','template']); + grunt.registerTask('serve', 'start web server to use in designer', function() { + grunt.event.once('connect.server.listening', function(host, port) { + var specRunnerUrl = 'http://' + host + ':' + 9001; + grunt.log.writeln('Tell the designer to load: ' + specRunnerUrl + "/component.html"); + }); + + grunt.task.run('connect:server'); + }); + grunt.registerTask('default', 'help message', function() { + grunt.log.writeln('\'grunt serve\' to display the test runner page'); + }); + grunt.registerTask('default', ['customize']); + // grunt.registerTask( "default", [ "csslint", "jshint", "inlinelint"]); +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..8da26bd --- /dev/null +++ b/package.json @@ -0,0 +1,33 @@ +{ + "name": "start-here", + "version": "0.1.0", + "description": "Forkable component for Mozilla Appmaker", + "main": "none", + "scripts": { + "test": "grunt" + }, + "repository": { + "type": "git", + "url": "git@github.com:mozilla-appmaker/start-here" + }, + "keywords": [ + "appmaker", + "webcomponents", + "ceci" + ], + "author": "David Ascher", + "license": "MPL-v2", + "bugs": { + "url": "https://github.com/mozilla-appmaker/start-here/issues" + }, + "devDependencies": { + "grunt-contrib-watch": "~0.5.3", + "grunt-contrib-jshint": "~0.8.0", + "grunt": "~0.4.2", + "grunt-contrib-csslint": "~0.2.0", + "grunt-lint-inline": "~0.4.0", + "grunt-contrib-connect": "~0.6.0", + "grunt-prompt": "~0.1.2", + "grunt-template": "~0.2.2" + } +} diff --git a/template/.gitignore b/template/.gitignore new file mode 100644 index 0000000..074e4e8 --- /dev/null +++ b/template/.gitignore @@ -0,0 +1,59 @@ +# Compiled source # +################### +*.com +*.class +*.dll +*.exe +*.o +*.so + +# Packages # +############ +# it's better to unpack these files and commit the raw source +# git has its own built in compression methods +*.7z +*.dmg +*.gz +*.iso +*.jar +*.rar +*.tar +*.zip + +# Logs and databases # +###################### +*.log +*.sql +*.sqlite + +# OS generated files # +###################### +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Node-specific stuff # +####################### + +lib-cov +lcov.info +*.seed +*.log +*.csv +*.dat +*.out +*.pid +*.gz + +pids +logs +results +build +.grunt + +node_modules + diff --git a/template/.travis.yml b/template/.travis.yml new file mode 100755 index 0000000..fde32f5 --- /dev/null +++ b/template/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - "0.10" +before_script: + - export DISPLAY=:99.0 + - sh -e /etc/init.d/xvfb start diff --git a/template/component.css b/template/component.css new file mode 100644 index 0000000..84d46f5 --- /dev/null +++ b/template/component.css @@ -0,0 +1,34 @@ +:host { + display: block; + width: 100%; + height: 50px; +} + +:host button { + font-family: "FiraSans", sans-serif; + cursor: pointer; + position: relative; + text-decoration: none; + outline: none; + border-top: 1px solid rgba(255,255,255,.3); + border-bottom: 2px solid rgba(0,0,0,.2); + background-color: #4DB227; + text-align: center; + display: block; + padding-top: 5px; + padding-bottom: 3px; + text-overflow: ellipsis; + overflow: hidden; + border-radius: 0.2rem; + font-weight: 600; + font-size: 1.8rem; + line-height: 3.8rem; + color: #ffffff; + width: 100%; + margin: 0; +} + +:host button { + border: none; +} + diff --git a/template/component.html b/template/component.html new file mode 100644 index 0000000..db08e74 --- /dev/null +++ b/template/component.html @@ -0,0 +1,91 @@ + + + + diff --git a/template/locale/en-US.json b/template/locale/en-US.json new file mode 100644 index 0000000..206e9eb --- /dev/null +++ b/template/locale/en-US.json @@ -0,0 +1,14 @@ +{ + "ceci-<%= name %>": "<%= name %>", + "ceci-<%= name %>/attributes/label": "Click Me", + "ceci-<%= name %>/attributes/label/label": "Label", + "ceci-<%= name %>/attributes/label/description": "Text shown on the button.", + "ceci-<%= name %>/attributes/value/label": "Value", + "ceci-<%= name %>/attributes/value/description": "Value sent by the button.", + "ceci-<%= name %>/attributes/textcolor/label": "Text Color", + "ceci-<%= name %>/attributes/textcolor/description": "Color of the text on the button's label.", + "ceci-<%= name %>/attributes/buttoncolor/label": "<%= name %> Color", + "ceci-<%= name %>/attributes/buttoncolor/description": "Background color of the button.", + "ceci-<%= name %>/attributes/buttonactivecolor/label": "Button Active Color", + "ceci-<%= name %>/attributes/buttonactivecolor/description": "Background color of the button while it is being clicked or tapped." +} diff --git a/thumbnail.png b/thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..e9c5e872cbc734b8d6df20f77adc2b903bc83908 GIT binary patch literal 13652 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 R`oBI^m624GC=)XZ{6ExZb29({ literal 0 HcmV?d00001