From a4179830e9e02373d02109d97adad13b03683d95 Mon Sep 17 00:00:00 2001 From: Dan Dascalescu Date: Thu, 27 Nov 2014 19:12:40 -0800 Subject: [PATCH] Move compatibility font files into separate package Also improve tests, publishing, README Link in the main README to the Meteor README after the Component section --- README.md | 23 ++++++++++++-- meteor/README.md | 33 ++++++++++++++++--- meteor/package-fontcompat.js | 33 +++++++++++++++++++ meteor/package.js | 7 +---- meteor/publish.sh | 59 ++++++++++++++++++++++++++-------- meteor/runtests.sh | 32 ++++++++++++------- meteor/test-fontcompat.js | 61 ++++++++++++++++++++++++++++++++++++ meteor/test.js | 43 ++++++++++++++++++------- 8 files changed, 240 insertions(+), 51 deletions(-) create mode 100644 meteor/package-fontcompat.js create mode 100644 meteor/test-fontcompat.js diff --git a/README.md b/README.md index 38a20b3460..cfa598627f 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ Stay up to date [@fontawesome](http://twitter.com/fontawesome). Get started at http://fontawesome.io! ##License + - The Font Awesome font is licensed under the SIL OFL 1.1: - http://scripts.sil.org/OFL - Font Awesome CSS, LESS, and SASS files are licensed under the MIT License: @@ -18,7 +19,9 @@ Get started at http://fontawesome.io! - `Font Awesome by Dave Gandy - http://fontawesome.io` - Full details: http://fontawesome.io/license + ##Changelog + - v3.0.0 - all icons redesigned from scratch, optimized for Bootstrap's 14px default - v3.0.1 - much improved rendering in webkit, various bug fixes - v3.0.2 - much improved rendering and alignment in IE7 @@ -38,7 +41,8 @@ Get started at http://fontawesome.io! Please read through our [contributing guidelines](https://github.com/FortAwesome/Font-Awesome/blob/master/CONTRIBUTING.md). Included are directions for opening issues, coding standards, and notes on development. -##Versioning + +## Versioning Font Awesome will be maintained under the Semantic Versioning guidelines as much as possible. Releases will be numbered with the following format: @@ -53,12 +57,15 @@ And constructed with the following guidelines: For more information on SemVer, please visit http://semver.org. -##Author + +## Author + - Email: dave@fontawesome.io - Twitter: http://twitter.com/davegandy - GitHub: https://github.com/davegandy -##Component + +## Component To include as a [component](http://github.com/component/component), just run $ component install FortAwesome/Font-Awesome @@ -69,6 +76,16 @@ Or add to the `dependencies` in your `component.json`. + +## Meteor + +To use Font Awesome integrates with the Meteor framework, run + + $ meteor add fortawesome:fontawesome + +Learn more about the [Meteor integration in the README](meteor/README.md). + + ## Hacking on Font Awesome From the root of the repository, install the tools used to develop. diff --git a/meteor/README.md b/meteor/README.md index c563959ff9..1c6e12182f 100644 --- a/meteor/README.md +++ b/meteor/README.md @@ -1,13 +1,36 @@ -Packaging Font Awesome for Meteor.js, the most popular -full-stack JavaScript framework on GitHub (http://meteor.com). +Packaging Font Awesome for [Meteor.js](http://meteor.com), the most popular full-stack JavaScript +framework on GitHub. + +[This package](https://atmospherejs.com/fortawesome/fontawesome) efficiently only loads the `woff` +font file, which is the only requirement for modern browsers. All wrapper packages you might still +find on Atmosphere bloat the client with unnecessary font files (SVG, EOT, TTF). + +If you need those files for compatibility with old browsers that still somehow run Meteor +(IE8, iOS < 5 or Android < 4.4), please see the +[fontawesome-compat](https://atmospherejs.com/fortawesome/fontawesome-compat) package. + + +# Meteor + +If you're new to Meteor, here's what the excitement is all about - +[watch the first two minutes](https://www.youtube.com/watch?v=fsi0aJ9yr2o); you'll be hooked by 1:28. + +That screencast is from 2012. In the meantime, Meteor has become a mature JavaScript-everywhere web +development framework with numerous [advantages](http://www.meteorpedia.com/read/Why_Meteor) over all +other single-page application frameworks. + +# Issues + +If you encounter an issue while using this package, please CC @dandv when you file it in this repo. + # DONE -* Tests that fonts are downloadable +* Tests that font(s) are downloadable * Visual check # TODO -* Figure out exactly what font files are needed and trim unnecessary ones (woff, eot, svg) - perhaps in specialized packages -* Read the `src/test.html` file into the test directly instead of via rawgit - how to do this with TinyTest? +* [Read the `src/test.html` file into the test directly](http://stackoverflow.com/questions/27180892/pull-an-html-file-into-a-tinytest) instead of via rawgit - how to do this with TinyTest? * Explain the magic behind how Meteor resolves CSS `@font-face src url('../fonts/...')` to the correct `/packages/.../fonts/...` path +* Add the [woff2 font before woff](http://stackoverflow.com/questions/11002820/why-should-we-include-ttf-eot-woff-svg-in-a-font-face/26945264#26945264) when it becomes available diff --git a/meteor/package-fontcompat.js b/meteor/package-fontcompat.js new file mode 100644 index 0000000000..d8fa172850 --- /dev/null +++ b/meteor/package-fontcompat.js @@ -0,0 +1,33 @@ +// package metadata file for Meteor.js + +var packageName = 'fortawesome:fontawesome-compat'; // http://atmospherejs.com/fortawesome:fontawesome-compat +var where = 'client'; // where to install: 'client', 'server', or ['client', 'server'] + +var packageJson = JSON.parse(Npm.require("fs").readFileSync('package.json')); + +Package.describe({ + name: packageName, + summary: 'Compatibility package for old browsers. Use fortawesome:fontawesome instead.', + version: packageJson.version, + git: 'https://github.com/FortAwesome/Font-Awesome/' +}); + +Package.onUse(function (api) { + api.versionsFrom('METEOR@0.9.2.1'); + api.addFiles([ + 'fonts/fontawesome-webfont.eot', // IE8 or older + 'fonts/fontawesome-webfont.svg', // SVG fallback for iOS < 5 - http://caniuse.com/#feat=svg-fonts, http://stackoverflow.com/a/11002874/1269037 + 'fonts/fontawesome-webfont.ttf', // Android Browers 4.1, 4.3 - http://caniuse.com/#feat=ttf + 'fonts/fontawesome-webfont.woff', // Most modern browsers + + 'css/font-awesome.css' + ], where); +}); + +Package.onTest(function (api) { + api.use(packageName, where); + api.use(['tinytest', 'http'], where); + + // TODO we should just bring in src/test.html - but how to do that with TinyTest? + api.addFiles('meteor/test-fontcompat.js', where); +}); diff --git a/meteor/package.js b/meteor/package.js index ba427fb07b..598ca47526 100644 --- a/meteor/package.js +++ b/meteor/package.js @@ -15,12 +15,7 @@ Package.describe({ Package.onUse(function (api) { api.versionsFrom('METEOR@0.9.2.1'); api.addFiles([ - 'fonts/FontAwesome.otf', // TODO What exactly does this file do? Can we get rid of it? - 'fonts/fontawesome-webfont.eot', // TODO What exactly does this file do? Can we get rid of it? - 'fonts/fontawesome-webfont.svg', // TODO What exactly does this file do? Can we get rid of it? - 'fonts/fontawesome-webfont.ttf', // This provides the actual font in Chrome - 'fonts/fontawesome-webfont.woff', // TODO What exactly does this file do? Can we get rid of it? - + 'fonts/fontawesome-webfont.woff', // Supported by all modern browsers. For compatibility with older browsers (that somehow still run Meteor), use the package-fontcompat.js file. 'css/font-awesome.css' ], where); }); diff --git a/meteor/publish.sh b/meteor/publish.sh index 45c12baabd..610ac7f3cd 100755 --- a/meteor/publish.sh +++ b/meteor/publish.sh @@ -4,20 +4,53 @@ type meteor >/dev/null 2>&1 || { curl https://install.meteor.com/ | sh; } # sanity check: make sure we're in the root directory of the checkout -DIR=$( cd "$( dirname "$0" )" && pwd ) -cd $DIR/.. +cd "$( dirname "$0" )/.." -# Meteor expects package.js to be in the root directory of the checkout, so copy it there temporarily -cp meteor/package.js ./ +# publish separately any package*.js files we have, e.g. package.js, package-compat.js +for PACKAGE_FILE in meteor/package*.js; do -# publish package, creating it if it's the first time we're publishing -PACKAGE_NAME=$(grep -i name package.js | head -1 | cut -d "'" -f 2) -PACKAGE_EXISTS=$(meteor search $PACKAGE_NAME 2>/dev/null | wc -l) + # Meteor expects package.js to be in the root directory of the checkout, so copy there our package file under that name, temporarily + cp $PACKAGE_FILE ./package.js -if [ $PACKAGE_EXISTS -gt 0 ]; then - meteor publish -else - meteor publish --create -fi + # publish package, creating it if it's the first time we're publishing + PACKAGE_NAME=$(grep -i name $PACKAGE_FILE | head -1 | cut -d "'" -f 2) + ATMOSPHERE_NAME=${PACKAGE_NAME/://} -rm package.js + echo "Publishing $PACKAGE_NAME..." + + # attempt to re-publish the package - the most common operation once the initial release has been made + POTENTIAL_ERROR=$( meteor publish 2>&1 ) + + if [[ $POTENTIAL_ERROR =~ "There is no package named" ]]; then + # actually this is the first time the package is created, so pass the special --create flag and congratulate the maintainer + echo "Thank you for creating the official Meteor package for this library!" + if meteor publish --create; then + echo "Success! Please post the following to https://github.com/raix/Meteor-community-discussions/issues/14: + +<<< ----------------------------------------- 8< -------------------------------------------------------- +Happy to announce that I've published the official $PACKAGE_NAME to Atmosphere. Please star! +https://atmospherejs.com/$ATMOSPHERE_NAME +>>> ----------------------------------------- >8 -------------------------------------------------------- + +" + else + echo "We got an error. Please post it at https://github.com/raix/Meteor-community-discussions/issues/14" + fi + else + if (( $? > 0 )); then + # the error wasn't that the package didn't exist, so we need to ask for help + echo "We got an error. Please post it at https://github.com/raix/Meteor-community-discussions/issues/14: +<<< ----------------------------------------- 8< -------------------------------------------------------- +$POTENTIAL_ERROR +>>> ----------------------------------------- >8 -------------------------------------------------------- +" + else + echo "Thanks for releasing a new version of $PACKAGE_NAME! You can see it at +https://atmospherejs.com/$ATMOSPHERE_NAME" + fi + fi + + # we copied the file as package.js, regardless of its original name + rm package.js + +done diff --git a/meteor/runtests.sh b/meteor/runtests.sh index eba0fd5cfb..e68df1b9b4 100755 --- a/meteor/runtests.sh +++ b/meteor/runtests.sh @@ -4,25 +4,33 @@ type meteor >/dev/null 2>&1 || { curl https://install.meteor.com/ | sh; } # sanity check: make sure we're in the root directory of the checkout -DIR=$( cd "$( dirname "$0" )" && pwd ) -cd $DIR/.. - -# Meteor expects package.js to be in the root directory of the checkout, so copy it there temporarily -cp meteor/package.js ./ +cd "$( dirname "$0" )/.." # run tests and delete the temporary package.js even if Ctrl+C is pressed int_trap() { echo - echo "Tests interrupted." + printf "Tests interrupted. Hopefully you verified in the browser that tests pass?\n\n" } trap int_trap INT -meteor test-packages ./ +# test any package*.js packages we may have, e.g. package.js, package-compat.js +for PACKAGE_FILE in meteor/package*.js; do + + PACKAGE_NAME=$(grep -i name $PACKAGE_FILE | head -1 | cut -d "'" -f 2) + + echo "Testing $PACKAGE_NAME..." + + # Meteor expects package.js to be in the root directory of the checkout, so copy there our package file under that name, temporarily + cp $PACKAGE_FILE ./package.js + + # provide an invalid MONGO_URL so Meteor doesn't bog us down with an empty Mongo database - + MONGO_URL=mongodb:// meteor test-packages ./ + + rm -rf ".build.$PACKAGE_NAME" + rm -rf ".build.local-test:$PACKAGE_NAME" + rm versions.json 2>/dev/null -PACKAGE_NAME=$(grep -i name package.js | head -1 | cut -d "'" -f 2) -rm -rf ".build.$PACKAGE_NAME" -rm -rf ".build.local-test:$PACKAGE_NAME" -rm versions.json 2>/dev/null + rm package.js -rm package.js +done diff --git a/meteor/test-fontcompat.js b/meteor/test-fontcompat.js new file mode 100644 index 0000000000..8feb9aa610 --- /dev/null +++ b/meteor/test-fontcompat.js @@ -0,0 +1,61 @@ +'use strict'; + +var packageName; // there seems to be no official way of finding out the name of the very package we're testing - http://stackoverflow.com/questions/27180709/in-a-tinytest-test-file-how-do-i-get-the-name-of-the-package + +// Check that the font files are downloadable. Meteor places assets at /packages//. +// Only the WOFF file is used in modern browsers. +['eot', 'svg', 'ttf', 'woff'].forEach(function (font) { + Tinytest.addAsync(font + ' fonts are shipped', function (test, done) { + + // curiously enough, the 'local-test:...' package isn't loaded into Package before calling Tinytest, so we can't do this determination outside this loop + if (!packageName) + Object.keys(Package).forEach(function(p) { + if (p.search(/local-test/) > -1) + packageName = p.replace('local-test:', ''); // we should stop the loop, but forEach can't do that + }); + + var packagePath = packageName.replace(':', '_'); // e.g. fortawesome_fontawesome + + HTTP.get( + '/packages/' + packagePath + '/fonts/fontawesome-webfont.' + font, + { + headers: { + 'Cache-Control': 'no-cache' // because Meteor has cached fonts even after they were removed from package.js (!) - https://github.com/meteor/meteor/issues/3196 + } + }, + function callback(error, result) { + if (error) { + test.fail({message: 'Font failed to load'}); + } else { + // if the file is 404, Meteor will redirect to / and return the Meteor.js boilerplate + test.isTrue(result.content.length > 30000, font + ' font could not be downloaded'); + } + + done(); + } + ); + }); +}); + + +// Visual check. Fonts are set by font-awesome.css in @font-face { src: url('../fonts/...') }. +// TODO How does Meteor find those occurrences in the source and resolve them to /packages//fonts/... ? +Tinytest.addAsync('Visual check', function (test, done) { + var iconsDropZone = document.createElement('div'); + document.body.appendChild(iconsDropZone); + + + // TODO ideally we'd get src/test.html straight from this repo, but no idea how to do this from TinyTest + HTTP.get('https://rawgit.com/FortAwesome/Font-Awesome/master/src/test.html', function callback(error, result) { + if (error) { + test.fail('Error getting the icons. Do we have an Internet connection to rawgit.com?'); + } else { + // [^] matches across newlines. Exclude the Stacked Icons section and below, because they transclude some other HTML. + iconsDropZone.innerHTML = result.content.match(/Stacked)/); + test.ok({message: 'Test passed if the icons look OK.'}); + } + + done(); + }); + +}); diff --git a/meteor/test.js b/meteor/test.js index a5f0e65133..aaa050838e 100644 --- a/meteor/test.js +++ b/meteor/test.js @@ -1,19 +1,39 @@ 'use strict'; +var packageName; // there seems to be no official way of finding out the name of the very package we're testing - http://stackoverflow.com/questions/27180709/in-a-tinytest-test-file-how-do-i-get-the-name-of-the-package + // Check that the font files are downloadable. Meteor places assets at /packages//. -// Only the TTF actually does anything in Chrome. -['eot', 'svg', 'ttf', 'woff'].forEach(function (font) { +// Only 'woff' for now, but we expect 'woff2' soon - https://github.com/FortAwesome/Font-Awesome/pull/5062#discussion_r20936453 +['woff'].forEach(function (font) { Tinytest.addAsync(font + ' fonts are shipped', function (test, done) { - HTTP.get('/packages/fortawesome_fontawesome/fonts/fontawesome-webfont.' + font, function callback(error, result) { - if (error) { - test.fail({message: 'Font failed to load'}); - } else { - test.isTrue(result.content.length > 10000, font + ' font could not be downloaded'); + // curiously enough, the 'local-test:...' package isn't loaded into Package before calling Tinytest, so we can't do this determination outside this loop + if (!packageName) + Object.keys(Package).forEach(function(p) { + if (p.search(/local-test/) > -1) + packageName = p.replace('local-test:', ''); // we should stop the loop, but forEach can't do that + }); + + var packagePath = packageName.replace(':', '_'); // e.g. fortawesome_fontawesome + + HTTP.get( + '/packages/' + packagePath + '/fonts/fontawesome-webfont.' + font, + { + headers: { + 'Cache-Control': 'no-cache' // because Meteor has cached fonts even after they were removed from package.js (!) - https://github.com/meteor/meteor/issues/3196 + } + }, + function callback(error, result) { + if (error) { + test.fail({message: 'Font failed to load'}); + } else { + // if the file is 404, Meteor will redirect to / and return the Meteor.js boilerplate + test.isTrue(result.content.length > 30000, font + ' font could not be downloaded'); + } + + done(); } - - done(); - }); + ); }); }); @@ -22,11 +42,10 @@ // TODO How does Meteor find those occurrences in the source and resolve them to /packages//fonts/... ? Tinytest.addAsync('Visual check', function (test, done) { var iconsDropZone = document.createElement('div'); - iconsDropZone.style.height = '10em'; document.body.appendChild(iconsDropZone); - // TODO ideally we'd get src/test HTML straight from this repo, but no idea how to do this from TinyTest + // TODO ideally we'd get src/test.html straight from this repo, but no idea how to do this from TinyTest HTTP.get('https://rawgit.com/FortAwesome/Font-Awesome/master/src/test.html', function callback(error, result) { if (error) { test.fail('Error getting the icons. Do we have an Internet connection to rawgit.com?');