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
This commit is contained in:
Dan Dascalescu 2014-11-27 19:12:40 -08:00
parent 0540aa0d54
commit ea0298788a
8 changed files with 245 additions and 54 deletions

View File

@ -8,6 +8,7 @@ Stay up to date [@fontawesome](http://twitter.com/fontawesome).
Get started at http://fontawesome.io! Get started at http://fontawesome.io!
##License ##License
- The Font Awesome font is licensed under the SIL OFL 1.1: - The Font Awesome font is licensed under the SIL OFL 1.1:
- http://scripts.sil.org/OFL - http://scripts.sil.org/OFL
- Font Awesome CSS, LESS, and SASS files are licensed under the MIT License: - 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` - `Font Awesome by Dave Gandy - http://fontawesome.io`
- Full details: http://fontawesome.io/license - Full details: http://fontawesome.io/license
##Changelog ##Changelog
- v3.0.0 - all icons redesigned from scratch, optimized for Bootstrap's 14px default - 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.1 - much improved rendering in webkit, various bug fixes
- v3.0.2 - much improved rendering and alignment in IE7 - 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). 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. 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 Font Awesome will be maintained under the Semantic Versioning guidelines as much as possible. Releases will be numbered
with the following format: with the following format:
@ -53,12 +57,15 @@ And constructed with the following guidelines:
For more information on SemVer, please visit http://semver.org. For more information on SemVer, please visit http://semver.org.
##Author
## Author
- Email: dave@fontawesome.io - Email: dave@fontawesome.io
- Twitter: http://twitter.com/davegandy - Twitter: http://twitter.com/davegandy
- GitHub: https://github.com/davegandy - GitHub: https://github.com/davegandy
##Component
## Component
To include as a [component](http://github.com/component/component), just run To include as a [component](http://github.com/component/component), just run
$ component install FortAwesome/Font-Awesome $ component install FortAwesome/Font-Awesome
@ -69,6 +76,16 @@ Or add
to the `dependencies` in your `component.json`. 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 ## Hacking on Font Awesome
From the root of the repository, install the tools used to develop. From the root of the repository, install the tools used to develop.

View File

@ -1,13 +1,38 @@
Packaging Font Awesome for Meteor.js, the most popular Packaging Font Awesome for [Meteor.js](http://meteor.com), the most popular full-stack JavaScript
full-stack JavaScript framework on GitHub (http://meteor.com). 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 # DONE
* Tests that fonts are downloadable * Tests that font(s) are downloadable
* Visual check * Visual check
# TODO # 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](http://stackoverflow.com/questions/27180892/pull-an-html-file-into-a-tinytest) instead of via rawgit - how to do this with TinyTest?
* Read the `src/test.html` file into the test directly 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 * 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

View File

@ -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.git'
});
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);
});

View File

@ -1,6 +1,6 @@
// package metadata file for Meteor.js // package metadata file for Meteor.js
var packageName = 'fortawesome:fontawesome'; // http://atmospherejs.com/fortawesome:fontawesome var packageName = 'fortawesome:fontawesome'; // http://atmospherejs.com/fortawesome/fontawesome
var where = 'client'; // where to install: 'client', 'server', or ['client', 'server'] var where = 'client'; // where to install: 'client', 'server', or ['client', 'server']
var packageJson = JSON.parse(Npm.require("fs").readFileSync('package.json')); var packageJson = JSON.parse(Npm.require("fs").readFileSync('package.json'));
@ -9,18 +9,13 @@ Package.describe({
name: packageName, name: packageName,
summary: 'Font Awesome (official): 470+ scalable vector icons, customizable via CSS, Retina friendly', summary: 'Font Awesome (official): 470+ scalable vector icons, customizable via CSS, Retina friendly',
version: packageJson.version, version: packageJson.version,
git: 'https://github.com/FortAwesome/Font-Awesome/' git: 'https://github.com/FortAwesome/Font-Awesome.git'
}); });
Package.onUse(function (api) { Package.onUse(function (api) {
api.versionsFrom('METEOR@0.9.2.1'); api.versionsFrom('METEOR@0.9.2.1');
api.addFiles([ api.addFiles([
'fonts/FontAwesome.otf', // 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.
'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?
'css/font-awesome.css' 'css/font-awesome.css'
], where); ], where);
}); });

View File

@ -4,20 +4,53 @@
type meteor >/dev/null 2>&1 || { curl https://install.meteor.com/ | sh; } 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 # sanity check: make sure we're in the root directory of the checkout
DIR=$( cd "$( dirname "$0" )" && pwd ) cd "$( dirname "$0" )/.."
cd $DIR/..
# Meteor expects package.js to be in the root directory of the checkout, so copy it there temporarily # publish separately any package*.js files we have, e.g. package.js, package-compat.js
cp meteor/package.js ./ for PACKAGE_FILE in meteor/package*.js; do
# publish package, creating it if it's the first time we're publishing # Meteor expects package.js to be in the root directory of the checkout, so copy there our package file under that name, temporarily
PACKAGE_NAME=$(grep -i name package.js | head -1 | cut -d "'" -f 2) cp $PACKAGE_FILE ./package.js
PACKAGE_EXISTS=$(meteor search $PACKAGE_NAME 2>/dev/null | wc -l)
if [ $PACKAGE_EXISTS -gt 0 ]; then # publish package, creating it if it's the first time we're publishing
meteor publish PACKAGE_NAME=$(grep -i name $PACKAGE_FILE | head -1 | cut -d "'" -f 2)
else ATMOSPHERE_NAME=${PACKAGE_NAME/://}
meteor publish --create
fi
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

View File

@ -1,28 +1,36 @@
# Test Meteor package before publishing to Atmosphere.js # Test Meteor package before publishing to Atmospherejs.com
# Make sure Meteor is installed, per https://www.meteor.com/install. The curl'ed script is totally safe; takes 2 minutes to read its source and check. # Make sure Meteor is installed, per https://www.meteor.com/install. The curl'ed script is totally safe; takes 2 minutes to read its source and check.
type meteor >/dev/null 2>&1 || { curl https://install.meteor.com/ | sh; } 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 # sanity check: make sure we're in the root directory of the checkout
DIR=$( cd "$( dirname "$0" )" && pwd ) cd "$( dirname "$0" )/.."
cd $DIR/..
# Meteor expects package.js to be in the root directory of the checkout, so copy it there temporarily
cp meteor/package.js ./
# run tests and delete the temporary package.js even if Ctrl+C is pressed # run tests and delete the temporary package.js even if Ctrl+C is pressed
int_trap() { int_trap() {
echo echo
echo "Tests interrupted." printf "Tests interrupted. Hopefully you verified in the browser that tests pass?\n\n"
} }
trap int_trap INT 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.js | head -1 | cut -d "'" -f 2) PACKAGE_NAME=$(grep -i name $PACKAGE_FILE | 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 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
rm package.js
done

61
meteor/test-fontcompat.js Normal file
View File

@ -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/<packageName>/.
// 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/<packageName>/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(/<section[^]+(?=<h3>Stacked)/);
test.ok({message: 'Test passed if the icons look OK.'});
}
done();
});
});

View File

@ -1,19 +1,39 @@
'use strict'; '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/<packageName>/. // Check that the font files are downloadable. Meteor places assets at /packages/<packageName>/.
// Only the TTF actually does anything in Chrome. // Only 'woff' for now, but we expect 'woff2' soon - https://github.com/FortAwesome/Font-Awesome/pull/5062#discussion_r20936453
['eot', 'svg', 'ttf', 'woff'].forEach(function (font) { ['woff'].forEach(function (font) {
Tinytest.addAsync(font + ' fonts are shipped', function (test, done) { Tinytest.addAsync(font + ' fonts are shipped', function (test, done) {
HTTP.get('/packages/fortawesome_fontawesome/fonts/fontawesome-webfont.' + font, function callback(error, result) { // 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 (error) { if (!packageName)
test.fail({message: 'Font failed to load'}); Object.keys(Package).forEach(function(p) {
} else { if (p.search(/local-test/) > -1)
test.isTrue(result.content.length > 10000, font + ' font could not be downloaded'); packageName = p.replace('local-test:', ''); // we should stop the loop, but forEach can't do that
} });
done(); 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();
}
);
}); });
}); });
@ -22,11 +42,10 @@
// TODO How does Meteor find those occurrences in the source and resolve them to /packages/<packageName>/fonts/... ? // TODO How does Meteor find those occurrences in the source and resolve them to /packages/<packageName>/fonts/... ?
Tinytest.addAsync('Visual check', function (test, done) { Tinytest.addAsync('Visual check', function (test, done) {
var iconsDropZone = document.createElement('div'); var iconsDropZone = document.createElement('div');
iconsDropZone.style.height = '10em';
document.body.appendChild(iconsDropZone); 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) { HTTP.get('https://rawgit.com/FortAwesome/Font-Awesome/master/src/test.html', function callback(error, result) {
if (error) { if (error) {
test.fail('Error getting the icons. Do we have an Internet connection to rawgit.com?'); test.fail('Error getting the icons. Do we have an Internet connection to rawgit.com?');