From 7059579c7499337c7946f3877ce77dd9a04ea22a Mon Sep 17 00:00:00 2001 From: Igor Minar Date: Fri, 15 Oct 2010 21:38:41 -0700 Subject: [PATCH] inline all images into css * embedded images as data URIs * rake task to generate multipart js file with embeded images for IE * move images into a separate directory outside of src or css and keep them there for reference * clean up Rakefile and ruby code * .gitignore update * don't penalize IE 8+ with an extra request to the ie-compat.js file --- .gitignore | 2 +- Rakefile | 179 ++++++++++++++---- css/angular.css | 109 +---------- css/angular_images/arrow_ascend.png | Bin 3093 -> 0 bytes css/angular_images/arrow_descend.png | Bin 3076 -> 0 bytes css/angular_images/loader-bar.gif | Bin 10819 -> 0 bytes .../css}/arrow_left.gif | Bin .../css}/arrow_right.gif | Bin .../css}/indicator-wait.png | Bin {logo => images/logo}/ng-logo.html | 0 {logo => images/logo}/ng-logo.png | Bin src/Angular.js | 19 +- src/Browser.js | 17 +- src/angular-bootstrap.js | 12 ++ 14 files changed, 185 insertions(+), 153 deletions(-) delete mode 100644 css/angular_images/arrow_ascend.png delete mode 100644 css/angular_images/arrow_descend.png delete mode 100644 css/angular_images/loader-bar.gif rename {css/angular_images => images/css}/arrow_left.gif (100%) rename {css/angular_images => images/css}/arrow_right.gif (100%) rename {css/angular_images => images/css}/indicator-wait.png (100%) rename {logo => images/logo}/ng-logo.html (100%) rename {logo => images/logo}/ng-logo.png (100%) diff --git a/.gitignore b/.gitignore index 7d148c85..89e7f0f2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,8 @@ angular-minified.map -externs.js angular.js angular-minified.js angular-debug.js +angular-ie-compat.js angular-scenario.js angularjs.netrc jstd.log diff --git a/Rakefile b/Rakefile index fc20dc01..bea458b2 100644 --- a/Rakefile +++ b/Rakefile @@ -38,36 +38,38 @@ GENERATED_FILES = [ 'angular-debug.js', 'angular-minified.js', 'angular-minified.map', + 'angular-ie-compat.js', 'angular-scenario.js', ] task :default => [:compile, :test] -desc 'Generate Externs' -task :compile_externs do - out = File.new("externs.js", "w") - - out.write("function jQuery(){};\n") - file = File.new("lib/jquery/jquery-1.4.2.js", "r") - while (line = file.gets) - if line =~ /^\s*(\w+)\s*:\s*function.*$/ - out.write("jQuery.#{$1}=function(){};\n") - end - end - file.close - out.write("jQuery.scope=function(){};\n") - out.write("jQuery.controller=function(){};\n") - - out.close -end desc 'Clean Generated Files' -task :clean do - GENERATED_FILES.each do |file| - `rm #{file}` +task :clean do + FileUtils.rm(GENERATED_FILES, :force => true) +end + + +desc 'Generate Externs' +task :compile_externs do + File.open('externs.js', 'w') do |out| + out.write("function jQuery(){};\n") + + File.open('lib/jquery/jquery-1.4.2.js', 'r') do |file| + while (line = file.gets) + if line =~ /^\s*(\w+)\s*:\s*function.*$/ + out.write("jQuery.#{$1}=function(){};\n") + end + end + end + + out.write("jQuery.scope=function(){};\n") + out.write("jQuery.controller=function(){};\n") end end + desc 'Compile Scenario' task :compile_scenario do @@ -78,28 +80,89 @@ task :compile_scenario do ANGULAR_SCENARIO, 'src/scenario/angular.suffix', ] - css = %x(cat css/angular-scenario.css) + concat = 'cat ' + deps.flatten.join(' ') - f = File.new("angular-scenario.js", 'w') - f.write(%x{#{concat}}) - f.write('document.write(\'\');') - f.close + + File.open('angular-scenario.js', 'w') do |f| + f.write(%x{#{concat}}) + f.write(gen_css('css/angular.css')) + f.write(gen_css('css/angular-scenario.css')) + end end + + + + +desc 'Generate IE css js patch' +task :generate_ie_compat do + css = File.open('css/angular.css', 'r') {|f| f.read } + + # finds all css rules that contain backround images and extracts the rule name(s), content type of + # the image and base64 encoded image data + r = /\n([^\{\n]+)\s*\{[^\}]*background-image:\s*url\("data:([^;]+);base64,([^"]+)"\);[^\}]*\}/ + + images = css.scan(r) + + # create a js file with multipart header containing the extracted images. the entire file *must* + # be CRLF (\r\n) delimited + File.open('angular-ie-compat.js', 'w') do |f| + f.write("/*\r\n" + + "Content-Type: multipart/related; boundary=\"_\"\r\n" + + "\r\n") + images.each_index do |idx| + f.write("--_\r\n" + + "Content-Location:img#{idx}\r\n" + + "Content-Transfer-Encoding:base64\r\n" + + "\r\n" + + images[idx][2] + "\r\n") + end + + f.write("--_--\r\n" + + "*/\r\n") + + # generate a css string containing *background-image rules for IE that point to the mime type + # images in the header + cssString = '' + images.each_index do |idx| + cssString += "#{images[idx][0]}{*background-image:url(\"mhtml:' + jsUri + '!img#{idx}\")}" + end + + # generate a javascript closure that contains a function which will append the generated css + # string as a stylesheet to the current html document + jsString = "(function(){ \r\n" + + " var jsUri = document.location.href.replace(/\\/[^\/]+(#.*)?$/, '/') + " + + " document.getElementById('ng-ie-compat').src; \r\n" + + " var css = '#{cssString}' \r\n" + + " var s = document.createElement('style'); \r\n" + + " s.setAttribute('type', 'text/css'); \r\n" + + " if (s.styleSheet) { \r\n" + + " s.styleSheet.cssText = css; \r\n" + + " } else { \r\n" + + " s.appendChild(document.createTextNode(css)); \r\n" + + " } \r\n" + + " document.getElementsByTagName('head')[0].appendChild(s); \r\n" + + "})();\r\n" + + f.write(jsString) + end +end + + desc 'Compile JavaScript' -task :compile => [:compile_externs, :compile_scenario] do +task :compile => [:compile_externs, :compile_scenario, :generate_ie_compat] do deps = [ 'src/angular.prefix', ANGULAR, 'src/angular.suffix', ] - f = File.new("angular-debug.js", 'w') - concat = 'cat ' + deps.flatten.join(' ') - f.write(%x{#{concat}}) - f.close + + File.open('angular-debug.js', 'w') do |f| + concat = 'cat ' + deps.flatten.join(' ') + f.write(%x{#{concat}}) + f.write(gen_css('css/angular.css', true)) + end %x(java -jar lib/compiler-closure/compiler.jar \ --compilation_level SIMPLE_OPTIMIZATIONS \ @@ -109,6 +172,7 @@ task :compile => [:compile_externs, :compile_scenario] do --js_output_file angular-minified.js) end + desc 'Create angular distribution' task :package => :compile do date = Time.now.strftime('%y%m%d_%H%M') @@ -117,44 +181,81 @@ task :package => :compile do %x(cp test/angular-mocks.js ./) - %x(tar -cf #{filename} \ + %x(tar -czf #{filename} \ angular-debug.js \ angular-minified.js \ angular-scenario.js \ angular-mocks.js \ - css/angular.css \ - css/angular_images/ ) + angular-ie-compat.js ) %x( rm angular-mocks.js) puts "Package created: #{filename}" end + namespace :server do + desc 'Run JsTestDriver Server' task :start do sh %x(java -jar lib/jstestdriver/JsTestDriver.jar --browser open --port 9876) end - desc "Run JavaScript tests against the server" + desc 'Run JavaScript tests against the server' task :test do sh %(java -jar lib/jstestdriver/JsTestDriver.jar --tests all) end + end -desc "Run JavaScript tests" + +desc 'Run JavaScript tests' task :test do sh %(java -jar lib/jstestdriver/JsTestDriver.jar --tests all --browser open --port 9876) end + desc 'Lint' task :lint do out = %x(lib/jsl/jsl -conf lib/jsl/jsl.default.conf) print out end + desc 'push_angularjs' -task :push_angularjs do - Rake::Task['compile'].execute 0 +task :push_angularjs => :compile do sh %(cat angularjs.ftp | ftp -N angularjs.netrc angularjs.org) end + + + +################### +# utility methods # +################### + + +## +# generates css snippet from a given files and optionally applies simple minification rules +# +def gen_css(cssFile, minify = false) + css = '' + File.open(cssFile, 'r') do |f| + css = f.read + end + + if minify + css.gsub! /\n/, '' + css.gsub! /\/\*.*?\*\//, '' + css.gsub! /:\s+/, ':' + css.gsub! /\s*\{\s*/, '{' + css.gsub! /\s*\}\s*/, '}' + css.gsub! /\s*\,\s*/, ',' + css.gsub! /\s*\;\s*/, ';' + end + + #escape for js + css.gsub! /'/, "\\'" + css.gsub! /\n/, "\\n" + + return %Q{document.write('');} +end \ No newline at end of file diff --git a/css/angular.css b/css/angular.css index 0fb10cdf..a293e8eb 100644 --- a/css/angular.css +++ b/css/angular.css @@ -1,32 +1,4 @@ @charset "UTF-8"; -/* CSS Document */ - -#ng-console { - border: thin solid black; - font-family: 'courier'; - font-size: x-small; -} - -#ng-console .ng-console-error { - color: red; -} - -#ng-console .ng-console-info { - color: blue; -} - -.ng-upload-widget object { - align:center; -} - -.ng-upload-widget a { - margin-right: .3em; -} - -.ng-upload-widget span { - color: #999999; - font-size: smaller; -} .ng-format-negative { color: red; @@ -42,29 +14,6 @@ border: 2px solid #FF0000; } -.ng-hidden { - display:none; -} - -/***************** - * DatePicker - *****************/ - -div.ui-widget { - font-size: 11px; - } - -/***************** - * OrderBy - *****************/ -.ng-ascend, -.ng-descend { - padding-right: 20px; - background-repeat: no-repeat; - background-position: right; -} -.ng-ascend { background-image: url(angular_images/arrow_ascend.png); } -.ng-descend { background-image: url(angular_images/arrow_descend.png); } /***************** * TIP @@ -83,7 +32,7 @@ div.ui-widget { } #ng-callout .ng-arrow-left{ - background-image: url(angular_images/arrow_left.gif); + background-image: url("data:image/gif;base64,R0lGODlhCwAXAKIAAMzMzO/v7/f39////////wAAAAAAAAAAACH5BAUUAAQALAAAAAALABcAAAMrSLoc/AG8FeUUIN+sGebWAnbKSJodqqlsOxJtqYooU9vvk+vcJIcTkg+QAAA7"); background-repeat: no-repeat; background-position: left top; position: absolute; @@ -95,7 +44,7 @@ div.ui-widget { } #ng-callout .ng-arrow-right{ - background-image: url(angular_images/arrow_right.gif); + background-image: url("data:image/gif;base64,R0lGODlhCwAXAKIAAMzMzO/v7/f39////////wAAAAAAAAAAACH5BAUUAAQALAAAAAALABcAAAMrCLTcoM29yN6k9socs91e5X3EyJloipYrO4ohTMqA0Fn2XVNswJe+H+SXAAA7"); background-repeat: no-repeat; background-position: left top; position: absolute; @@ -117,7 +66,6 @@ div.ui-widget { color:#333333; } - #ng-callout .ng-title{ background-color: #CCCCCC; text-align: left; @@ -128,62 +76,11 @@ div.ui-widget { } -#ng-spacer { - height: 1.2em; -} - -#ng-loading { - position: fixed; - bottom: 0; - height: 1.2em; - width: 100%; - text-align: center; -} - -/***************** - * Login - *****************/ - -#ng-login { - z-index: 2000; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - padding-top: 100px; -} - -#ng-login .ng-login-container { - width: 500px; - height: 380px; - margin: auto; - border-top: 5px solid #FFF; - border-left: 5px solid #DDD; - border-right: 5px solid #777; - border-bottom: 5px solid #555; - padding: 0 3px 3px 0; -} - -#ng-login .ng-login-container iframe { - width: 100%; - height: 100%; - border: 2px solid black; -} - - /***************** * indicators *****************/ -.ng-indicator-wait { - display: inline-block; - height: 16px; - width: 16px; - background-image: url("angular_images/indicator-wait.png"); -} - .ng-input-indicator-wait { - background-image: url("angular_images/indicator-wait.png"); + background-image: url("data:image/png;base64,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"); background-position: right; background-repeat: no-repeat; } diff --git a/css/angular_images/arrow_ascend.png b/css/angular_images/arrow_ascend.png deleted file mode 100644 index dd27b92baa6c2983fc129d45d6a1355fd9b32980..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3093 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 diff --git a/css/angular_images/arrow_descend.png b/css/angular_images/arrow_descend.png deleted file mode 100644 index ec1cb5dffd3941a606c4afc9e4cd4512cca01b60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3076 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 g|2k@-t6V^D=-lN;QH?)nSWpZ53kcXZ~y=R diff --git a/css/angular_images/arrow_left.gif b/images/css/arrow_left.gif similarity index 100% rename from css/angular_images/arrow_left.gif rename to images/css/arrow_left.gif diff --git a/css/angular_images/arrow_right.gif b/images/css/arrow_right.gif similarity index 100% rename from css/angular_images/arrow_right.gif rename to images/css/arrow_right.gif diff --git a/css/angular_images/indicator-wait.png b/images/css/indicator-wait.png similarity index 100% rename from css/angular_images/indicator-wait.png rename to images/css/indicator-wait.png diff --git a/logo/ng-logo.html b/images/logo/ng-logo.html similarity index 100% rename from logo/ng-logo.html rename to images/logo/ng-logo.html diff --git a/logo/ng-logo.png b/images/logo/ng-logo.png similarity index 100% rename from logo/ng-logo.png rename to images/logo/ng-logo.png diff --git a/src/Angular.js b/src/Angular.js index 79557c2c..8cacb9e4 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -32,7 +32,8 @@ var _undefined = undefined, PRIORITY = {'FIRST': PRIORITY_FIRST, 'LAST': PRIORITY_LAST, 'WATCH':PRIORITY_WATCH}, jQuery = window['jQuery'] || window['$'], // weirdness to make IE happy _ = window['_'], - msie = !!/(msie) ([\w.]+)/.exec(lowercase(navigator.userAgent)), + /** holds major version number for IE or NaN for real browsers */ + msie = parseInt((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1], 10), jqLite = jQuery || jqLiteWrap, slice = Array.prototype.slice, push = Array.prototype.push, @@ -408,25 +409,31 @@ function toKeyValue(obj) { function angularInit(config){ if (config.autobind) { // TODO default to the source of angular.js - var scope = compile(window.document, _null, {'$config':config}); + var scope = compile(window.document, _null, {'$config':config}), + $browser = scope.$inject('$browser'); + if (config.css) - scope.$inject('$browser').addCss(config.base_url + config.css); + $browser.addCss(config.base_url + config.css); + else if(msie<8) + $browser.addJs(config.base_url + config.ie_compat, config.ie_compat_id); + scope.$init(); } } function angularJsConfig(document, config) { - var filename = /^(.*)\/angular(-([^\/]*))?.js(\?[^#]*)?(#(.*))?$/, + var filename = /^(.*)angular(-([^\/]*))?.js(\?[^#]*)?(#(.*))?$/, scripts = document.getElementsByTagName("script"), match; config = extend({ base_url: '', - css: '../css/angular.css' + ie_compat: 'angular-ie-compat.js', + ie_compat_id: 'ng-ie-compat' }, config); for(var j = 0; j < scripts.length; j++) { match = (scripts[j].src || "").match(filename); if (match) { - config.base_url = match[1] + '/'; + config.base_url = match[1]; extend(config, parseKeyValue(match[6])); eachAttribute(jqLite(scripts[j]), function(value, name){ if (/^ng:/.exec(name)) { diff --git a/src/Browser.js b/src/Browser.js index aa80ef47..dcdc0a73 100644 --- a/src/Browser.js +++ b/src/Browser.js @@ -188,11 +188,26 @@ function Browser(location, document, head, XHR, $log) { }; - self.addCss = function(url) { + /** + * Adds a stylesheet tag to the head. + */ + self.addCss = function(/**string*/url) { var link = jqLite(rawDocument.createElement('link')); link.attr('rel', 'stylesheet'); link.attr('type', 'text/css'); link.attr('href', url); head.append(link); }; + + + /** + * Adds a script tag to the head. + */ + self.addJs = function(/**string*/url, /**string*/dom_id) { + var script = jqLite(rawDocument.createElement('script')); + script.attr('type', 'text/javascript'); + script.attr('src', url); + if (dom_id) script.attr('id', dom_id); + head.append(script); + }; } diff --git a/src/angular-bootstrap.js b/src/angular-bootstrap.js index 4c95e8b0..416acbde 100644 --- a/src/angular-bootstrap.js +++ b/src/angular-bootstrap.js @@ -37,6 +37,13 @@ document.write(''); } + function addCss(file) { + document.write(''); + } + + addCss("/angular.css"); + addScript("/Angular.js"); addScript("/JSON.js"); addScript("/Compiler.js"); @@ -58,10 +65,15 @@ addScript("/markups.js"); addScript("/widgets.js"); + window.onload = function(){ try { if (previousOnLoad) previousOnLoad(); } catch(e) {} + + //angular-ie-compat.js needs to be pregenerated for development with IE<8 + if (msie<8) addScript('../angular-ie-compat.js'); + angularInit(angularJsConfig(document)); };