Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

update to webassets 0.8 and reorg assets

Lots of reorganization and awesome changes to the asset pipeline.

 - split out assets.py from resources.py
 - integrate requirements into pyramid_layout to let layouts declare
   requirements in addition to those conferred by the forms used
 - change 'scss' directory to 'css'
 - remove 'js/src' dir
 - move 'js/lib' to 'lib'
  • Loading branch information...
commit 48ac6073f52db4f9f44eb261a8debd30cb4574fe 1 parent b3458f8
@tilgovi tilgovi authored
Showing with 199 additions and 257 deletions.
  1. +0 −3  .gitignore
  2. +1 −0  h/__init__.py
  3. +168 −0 h/assets.py
  4. 0  h/{sass → css}/app.scss
  5. 0  h/{sass → css}/base.scss
  6. 0  h/{sass → css}/common.scss
  7. 0  h/{sass → css}/inject.scss
  8. 0  h/{sass → css}/reset.scss
  9. 0  h/{sass → css}/site.scss
  10. 0  h/js/{src → }/app.coffee
  11. 0  h/js/{src → }/controllers.coffee
  12. 0  h/js/{src → }/deform.coffee
  13. 0  h/js/{src → }/directives.coffee
  14. 0  h/js/{lib → }/helpers.js
  15. 0  h/js/{src/annotator.host.coffee → inject/host.coffee}
  16. 0  h/js/{src → }/plugin/heatmap.coffee
  17. 0  h/js/{src → }/services.coffee
  18. +26 −12 h/layouts.py
  19. 0  h/{js → }/lib/Markdown.Converter.js
  20. 0  h/{js → }/lib/Markdown.Sanitizer.js
  21. 0  h/{js → }/lib/angular.min.js
  22. 0  h/{js → }/lib/annotator.auth.min.js
  23. 0  h/{js → }/lib/annotator.min.js
  24. 0  h/{js → }/lib/annotator.permissions.min.js
  25. 0  h/{js → }/lib/annotator.store.min.js
  26. 0  h/{js → }/lib/d3.v2.min.js
  27. 0  h/{js → }/lib/easyXDM.min.js
  28. 0  h/{js → }/lib/handlebars-runtime.min.js
  29. 0  h/{js → }/lib/jquery.mousewheel.min.js
  30. 0  h/{js → }/lib/jwz.min.js
  31. 0  h/{js → }/lib/polyfills/raf.js
  32. 0  h/{js → }/lib/underscore-min.js
  33. +0 −209 h/resources.py
  34. +0 −19 h/templates/app.pt
  35. +0 −2  h/templates/base.pt
  36. +1 −1  h/templates/embed.txt
  37. +0 −4 h/templates/home.pt
  38. +1 −5 h/views.py
  39. +2 −2 requirements.txt
View
3  .gitignore
@@ -17,6 +17,3 @@
*.pyc
*.pyo
-
-/h/css/site.css
-/h/js/lib/annotator
View
1  h/__init__.py
@@ -6,6 +6,7 @@
def includeme(config):
config.include('h.api')
config.include('h.app')
+ config.include('h.assets')
config.include('h.forms')
config.include('h.layouts')
config.include('h.models')
View
168 h/assets.py
@@ -0,0 +1,168 @@
+import re
+
+from webassets import Bundle
+from webassets.loaders import PythonLoader
+
+
+def Uglify(*names, **kw):
+ kw.setdefault('filters', 'uglifyjs')
+ return Bundle(*names, **kw)
+
+
+def Coffee(*names, **kw):
+ kw.setdefault('filters', 'coffeescript')
+ return Bundle(*names, **kw)
+
+
+def SCSS(*names, **kw):
+ kw.setdefault('filters', 'cleancss,compass,cssrewrite')
+ return Bundle(*names, **kw)
+
+
+def Handlebars(*names, **kw):
+ kw.setdefault('filters', 'handlebars')
+ return Bundle(*names, **kw)
+
+
+# Included dependencies
+annotator = Bundle('h:lib/annotator.min.js', 'h:lib/annotator.*.min.js')
+angular = Bundle('h:lib/angular.min.js')
+d3 = Bundle('h:lib/d3.v2.min.js')
+easyXDM = Bundle('h:lib/easyXDM.min.js')
+jwz = Bundle('h:lib/jwz.min.js')
+pagedown = Uglify('h:lib/Markdown.Converter.js', 'h:lib/Markdown.Sanitizer.js')
+raf = Uglify('h:lib/polyfills/raf.js')
+underscore = Bundle('h:lib/underscore-min.js')
+
+
+# External dependencies
+jquery = Bundle('deform:static/scripts/jquery-1.7.2.min.js')
+deform = Bundle(
+ jquery,
+ Uglify(
+ 'deform:static/scripts/jquery.form-3.09.js',
+ 'deform:static/scripts/deform.js',
+ output='js/deform.min.js'
+ )
+)
+
+
+# Handlebars templates
+templates = Bundle(
+ 'h:lib/handlebars-runtime.min.js',
+ Uglify(
+ 'h:js/helpers.js',
+ Handlebars('h:templates/*.handlebars', output='js/templates.js'),
+ output='js/templates.min.js'
+ ),
+)
+
+
+# Base and common SCSS
+base = ['h:css/base.scss']
+common = ['h:css/base.scss', 'h:css/common.scss']
+
+
+# Main resource bundles
+app = Bundle(
+ jquery,
+ angular,
+ annotator,
+ deform,
+ d3,
+ easyXDM,
+ jwz,
+ pagedown,
+ templates,
+ underscore,
+ 'h:lib/jquery.mousewheel.min.js',
+ 'deform_bootstrap:static/bootstrap.min.js',
+ Uglify(
+ *[
+ Coffee('h:/js/%s.coffee' % name,
+ output='js/%s.js' % name)
+ for name in
+ (
+ 'app',
+ 'deform',
+ 'directives',
+ 'controllers',
+ 'services',
+ )
+ ],
+ output='js/hypothesis.min.js'
+ ),
+ Uglify(
+ *[
+ Coffee('h:/js/plugin/%s.coffee' % name,
+ output='js/plugin/%s.js' % name)
+ for name in
+ (
+ 'heatmap',
+ )
+ ],
+ output='js/hypothesis.plugins.min.js'
+ ),
+ SCSS('h:css/app.scss', depends=(base + common), output='css/app.css'),
+)
+
+
+site = SCSS('h:css/site.scss', depends=(base + common), output='css/site.css')
+
+
+# The inject is a easyXDM consumer which loads the annotator in an iframe
+# and sets up a JSON-RPC channel for cross-domain communication between the
+# iframe and the host window.
+inject = Bundle(
+ easyXDM,
+ 'h:lib/annotator.min.js',
+ Uglify(
+ Coffee('h:js/inject/host.coffee', output='js/host.js'),
+ output='js/hypothesis-host.min.js'
+ ),
+ SCSS('h:css/inject.scss', depends=base, output='css/inject.css'),
+)
+
+
+class WebassetsResourceRegistry(object):
+ def __init__(self, env):
+ self.env = env
+
+ def __call__(self, requirements):
+ result = {'js': [], 'css': []}
+
+ urls = []
+ for name in zip(*requirements)[0]:
+ if name in self.env:
+ bundle = self.env[name]
+ urls.extend(bundle.urls())
+
+ for source in urls:
+ print source
+ # check asset type (js or css), modulo cache-busting qs
+ for thing in ('js', 'css'):
+ if re.search(r'\.%s(\??[^/]+)?$' % thing, source):
+ if not source in result[thing]:
+ result[thing].append(source)
+
+ print result
+ return result
+
+
+def includeme(config):
+ config.include('pyramid_webassets')
+
+ config.add_static_view('css', 'h:css')
+ config.add_static_view('js', 'h:js')
+ config.add_static_view('lib', 'h:lib')
+ config.add_static_view('images', 'h:images')
+
+ loader = PythonLoader(config.registry.settings.get('h.assets', __name__))
+ bundles = loader.load_bundles()
+ for name in bundles:
+ config.add_webasset(name, bundles[name])
+
+ from deform.field import Field
+ resource_registry = WebassetsResourceRegistry(config.get_webassets_env())
+ Field.set_default_resource_registry(resource_registry)
+ config.registry.resources = resource_registry
View
0  h/sass/app.scss → h/css/app.scss
File renamed without changes
View
0  h/sass/base.scss → h/css/base.scss
File renamed without changes
View
0  h/sass/common.scss → h/css/common.scss
File renamed without changes
View
0  h/sass/inject.scss → h/css/inject.scss
File renamed without changes
View
0  h/sass/reset.scss → h/css/reset.scss
File renamed without changes
View
0  h/sass/site.scss → h/css/site.scss
File renamed without changes
View
0  h/js/src/app.coffee → h/js/app.coffee
File renamed without changes
View
0  h/js/src/controllers.coffee → h/js/controllers.coffee
File renamed without changes
View
0  h/js/src/deform.coffee → h/js/deform.coffee
File renamed without changes
View
0  h/js/src/directives.coffee → h/js/directives.coffee
File renamed without changes
View
0  h/js/lib/helpers.js → h/js/helpers.js
File renamed without changes
View
0  h/js/src/annotator.host.coffee → h/js/inject/host.coffee
File renamed without changes
View
0  h/js/src/plugin/heatmap.coffee → h/js/plugin/heatmap.coffee
File renamed without changes
View
0  h/js/src/services.coffee → h/js/services.coffee
File renamed without changes
View
38 h/layouts.py
@@ -1,9 +1,11 @@
-from pyramid.decorator import reify
+from deform import Field
from pyramid_layout.layout import layout_config
@layout_config(template='h:templates/base.pt')
class BaseLayout(object):
+ requirements = ()
+
def __init__(self, context, request):
self.context = context
self.request = request
@@ -14,24 +16,36 @@ def add_form(self, form):
raise ValueError('duplicate form id "%s"' % form.formid)
self.forms[form.formid] = form
- @reify
- def resources(self):
- result = {'js': [], 'css': []}
+ def get_widget_requirements(self):
+ requirements = []
+ requirements.extend(self.requirements)
for form in self.forms.values():
- resources = form.get_widget_resources()
- for thing in ('js', 'css'):
- for source in resources[thing]:
- if not source in result[thing]:
- result[thing].append(source)
- return result
+ requirements.extend(form.get_widget_requirements())
+ return requirements
+
+ def get_widget_resources(self):
+ requirements = self.get_widget_requirements()
+ return Field.default_resource_registry(requirements)
@property
def css_links(self):
- return self.resources['css']
+ return self.get_widget_resources()['css']
@property
def js_links(self):
- return self.resources['js']
+ return self.get_widget_resources()['js']
+
+
+@layout_config(context='h.resources.AppFactory',
+ template='h:templates/base.pt')
+class AppLayout(BaseLayout):
+ requirements = (('app', None),)
+
+
+@layout_config(context='h.resources.RootFactory',
+ template='h:templates/base.pt')
+class SiteLayout(BaseLayout):
+ requirements = (('site', None),)
def includeme(config):
View
0  h/js/lib/Markdown.Converter.js → h/lib/Markdown.Converter.js
File renamed without changes
View
0  h/js/lib/Markdown.Sanitizer.js → h/lib/Markdown.Sanitizer.js
File renamed without changes
View
0  h/js/lib/angular.min.js → h/lib/angular.min.js
File renamed without changes
View
0  h/js/lib/annotator.auth.min.js → h/lib/annotator.auth.min.js
File renamed without changes
View
0  h/js/lib/annotator.min.js → h/lib/annotator.min.js
File renamed without changes
View
0  h/js/lib/annotator.permissions.min.js → h/lib/annotator.permissions.min.js
File renamed without changes
View
0  h/js/lib/annotator.store.min.js → h/lib/annotator.store.min.js
File renamed without changes
View
0  h/js/lib/d3.v2.min.js → h/lib/d3.v2.min.js
File renamed without changes
View
0  h/js/lib/easyXDM.min.js → h/lib/easyXDM.min.js
File renamed without changes
View
0  h/js/lib/handlebars-runtime.min.js → h/lib/handlebars-runtime.min.js
File renamed without changes
View
0  h/js/lib/jquery.mousewheel.min.js → h/lib/jquery.mousewheel.min.js
File renamed without changes
View
0  h/js/lib/jwz.min.js → h/lib/jwz.min.js
File renamed without changes
View
0  h/js/lib/polyfills/raf.js → h/lib/polyfills/raf.js
File renamed without changes
View
0  h/js/lib/underscore-min.js → h/lib/underscore-min.js
File renamed without changes
View
209 h/resources.py
@@ -1,211 +1,12 @@
-import re
-
from horus import resources
from pyramid.decorator import reify
from pyramid.interfaces import ILocation
-from webassets import Bundle
-from webassets.filter import register_filter
-from webassets.loaders import PythonLoader
-
from zope.interface import implementer
from h import api, models
-# register our backported cleancss filter until webassets 0.8 is released
-from h.cleancss import CleanCSS
-register_filter(CleanCSS)
-
-# The main annotation application is a combination of upstream Annotator
-# core components and plugins with additional downstream plugins from here.
-annotator = Bundle(
- Bundle(
- 'h:js/lib/annotator.min.js',
- 'h:js/lib/annotator.auth.min.js',
- 'h:js/lib/annotator.permissions.min.js',
- 'h:js/lib/annotator.store.min.js',
- ),
- Bundle('h:js/lib/jquery.mousewheel.min.js'),
- Bundle('deform_bootstrap:static/bootstrap.min.js'),
- Bundle(
- Bundle(
- Bundle(
- 'h:js/src/deform.coffee',
- debug=False,
- filters='coffeescript',
- output='js/deform.js',
- ),
- Bundle(
- 'h:js/src/app.coffee',
- debug=False,
- filters='coffeescript',
- output='js/app.js',
- ),
- Bundle(
- 'h:js/src/controllers.coffee',
- debug=False,
- filters='coffeescript',
- output='js/controllers.js',
- ),
- Bundle(
- 'h:js/src/directives.coffee',
- debug=False,
- filters='coffeescript',
- output='js/directives.js',
- ),
- Bundle(
- 'h:js/src/services.coffee',
- debug=False,
- filters='coffeescript',
- output='js/services.js',
- ),
- filters='uglifyjs',
- output='js/hypothesis.min.js'
- ),
- Bundle(
- Bundle(
- 'h:js/src/plugin/heatmap.coffee',
- debug=False,
- filters='coffeescript',
- output='js/lib/annotator.heatmap.js',
- ),
- filters='uglifyjs',
- output='js/lib/annotator.heatmap.min.js'
- ),
- output='js/hypothesis-full.min.js',
- ),
-)
-
-# The injector is a easyXDM consumer which loads the annotator in an iframe
-# and sets up a JSON-RPC channel for cross-domain communication between the
-# iframe and the host window.
-injector = Bundle(
- Bundle('h:js/lib/annotator.min.js'),
- Bundle(
- Bundle(
- 'h:js/src/annotator.host.coffee',
- debug=False,
- filters='coffeescript',
- output='js/annotator.host.js',
- ),
- filters='uglifyjs',
- output='js/hypothesis-host.min.js',
- ),
-)
-
-#
-# Application dependencies
-#
-
-angular = Bundle('h:js/lib/angular.min.js')
-d3 = Bundle('h:js/lib/d3.v2.min.js')
-easyXDM = Bundle('h:js/lib/easyXDM.min.js')
-handlebars = Bundle('h:js/lib/handlebars-runtime.min.js')
-jquery = Bundle('deform:static/scripts/jquery-1.7.2.min.js')
-jwz = Bundle('h:js/lib/jwz.min.js')
-
-deform = Bundle(
- jquery,
- Bundle(
- 'deform:static/scripts/jquery.form-3.09.js',
- 'deform:static/scripts/deform.js',
- )
-)
-
-# PageDown is used to render Markdown-formatted text to HTML
-pagedown = Bundle(
- Bundle(
- 'h:js/lib/Markdown.Converter.js',
- 'h:js/lib/Markdown.Sanitizer.js',
- ),
- filters='uglifyjs',
- output='js/markdown.min.js',
-)
-raf = Bundle('h:js/lib/polyfills/raf.js')
-underscore = Bundle('h:js/lib/underscore-min.js')
-
-# The user interface of the application is structured around these Handlebars
-# templates.
-_template = lambda tf: Bundle(
- 'h:templates/%s.handlebars' % tf,
- filters=('handlebars',),
- debug=False,
- output='js/templates/%s.js' % tf)
-templates = Bundle(
- _template('detail'),
- _template('editor'),
- _template('summary'),
- Bundle('h:js/lib/helpers.js'),
- filters=('uglifyjs',),
- output='js/hypothesis-templates.min.js',
-)
-
-# CSS specific to the application
-app_css = Bundle(
- Bundle(
- 'h:sass/app.scss',
- debug=False,
- depends=(
- 'h:sass/reset.scss',
- 'h:sass/base.scss',
- 'h:sass/common.scss',
- ),
- filters=('compass', 'cssrewrite',),
- output='css/app.css',
- ),
- filters=('cleancss',),
- output='css/app.min.css',
-)
-
-# Host-page CSS for widget placement.
-inject_css = Bundle(
- Bundle(
- 'h:sass/inject.scss',
- debug=False,
- depends=('h:sass/base.scss',),
- filters=('compass', 'cssrewrite',),
- output='css/inject.css',
- ),
- filters=('cleancss', 'datauri'),
- output=('css/inject.min.css'),
-)
-
-# CSS specific to the destination site
-site_css = Bundle(
- Bundle(
- 'h:sass/site.scss',
- debug=False,
- depends=(
- 'h:sass/reset.scss',
- 'h:sass/base.scss',
- 'h:sass/common.scss',
- ),
- filters=('compass', 'cssrewrite',),
- output='css/site.css',
- ),
- filters=('cleancss',),
- output='css/site.min.css',
-)
-
-
-class WebassetsResourceRegistry(object):
- def __init__(self, environment):
- self.environment = environment
-
- def __call__(self, requirements):
- result = {'js': [], 'css': []}
- for requirement, _version in requirements:
- if not requirement in self.environment:
- continue
- bundle = self.environment[requirement]
- for source in bundle.urls():
- for thing in ('js', 'css'):
- if re.search(r'/[^/?]+\.%s\??[^/]*$' % thing, source):
- if not source in result[thing]:
- result[thing].append(source)
- return result
-
@implementer(ILocation)
class BaseResource(resources.BaseFactory):
@@ -323,19 +124,9 @@ def token(self):
def includeme(config):
config.include('horus.routes')
- config.include('pyramid_webassets')
RootFactory.api = APIFactory
RootFactory.app = AppFactory
config.add_route('embed', '/embed.js')
config.add_route('index', '/', factory='h.resources.RootFactory')
-
- loader = PythonLoader(__name__)
- bundles = loader.load_bundles()
- for name in bundles:
- config.add_webasset(name, bundles[name])
-
- from deform.field import Field
- resource_registry = WebassetsResourceRegistry(config.get_webassets_env())
- Field.set_default_resource_registry(resource_registry)
View
19 h/templates/app.pt
@@ -1,11 +1,5 @@
<!DOCTYPE html>
<html lang="en" metal:use-macro="main_template">
- <head>
- <link rel="stylesheet"
- metal:fill-slot="css_links"
- tal:attributes="href href"
- tal:repeat="href webassets(request, 'app_css') | []" />
- </head>
<body data-ng-app="h"
data-ng-controller="Hypothesis"
metal:fill-slot="body">
@@ -87,18 +81,5 @@
<div id="wrapper">
</div>
</div>
- <script type="text/javascript"
- tal:attributes="src src"
- tal:repeat="src webassets(
- request,
- 'angular',
- 'annotator',
- 'd3',
- 'easyXDM',
- 'handlebars',
- 'jwz',
- 'pagedown',
- 'templates',
- 'underscore')"></script>
</body>
</html>
View
2  h/templates/base.pt
@@ -11,8 +11,6 @@
<link rel="stylesheet"
tal:attributes="href href"
tal:repeat="href layout.css_links | []" />
- <tal:block metal:define-slot="css_links" />
- <tal:block metal:define-slot="js_links" />
<script type="text/javascript"
tal:attributes="src src"
tal:repeat="src layout.js_links | []" ></script>
View
2  h/templates/embed.txt
@@ -9,7 +9,7 @@ yepnope([
},
{
test: window.Annotator,
- nope: Array.prototype.concat.call(${injector}, ${easyXDM}, ${inject_css}),
+ nope: Array.prototype.concat.call(${inject}),
complete: function () {
if (window.Annotator._instance) return;
View
4 h/templates/home.pt
@@ -1,10 +1,6 @@
<!DOCTYPE html>
<html lang="en" metal:use-macro="main_template">
<head>
- <link rel="stylesheet"
- metal:fill-slot="css_links"
- tal:attributes="href href"
- tal:repeat="href webassets(request, 'site_css') | []" />
<script type="text/javascript"
metal:fill-slot="embed"
tal:content="structure embed" />
View
6 h/views.py
@@ -16,7 +16,7 @@ def embed(request, standalone=True):
request.response.charset = 'UTF-8'
return {
pkg: json.dumps(request.webassets_env[pkg].urls())
- for pkg in ['easyXDM', 'injector', 'inject_css', 'jquery', 'raf']
+ for pkg in ['inject', 'jquery', 'raf']
}
@@ -28,10 +28,6 @@ def home(request):
def includeme(config):
- config.add_static_view('h/sass', 'h:sass')
- config.add_static_view('h/js', 'h:js')
- config.add_static_view('h/images', 'h:images')
-
config.add_view(
'horus.views.AuthController',
attr='login',
View
4 requirements.txt
@@ -40,7 +40,7 @@ pyramid-deform==0.2a5
pyramid-layout==0.4
pyramid-mailer==0.9
pyramid-tm==0.4
-pyramid-webassets==0.7
+-e git+https://github.com/tilgovi/pyramid_webassets.git@7ee74fa419fddc357c03d64a05b2e896dabad781#egg=pyramid_webassets-dev
pystache==0.5.2
pytest==2.2.4
python-openid==2.2.5
@@ -54,7 +54,7 @@ translationstring==1.1
unittest2==0.5.1
velruse==1.0
venusian==1.0a7
-webassets==0.7.1
+webassets==0.8
wsgiref==0.1.2
zope.deprecation==4.0.0
zope.interface==4.0.1
Please sign in to comment.
Something went wrong with that request. Please try again.