From 2ab481a1dacf84e8a19ef141e5b57e45052dff22 Mon Sep 17 00:00:00 2001
From: Yury Delendik <ydelendik@mozilla.com>
Date: Tue, 9 Jul 2013 17:14:21 -0500
Subject: [PATCH] Removes foreign for Firefox CSS prefixes

---
 external/builder/builder.js | 67 +++++++++++++++++++++++++++++++++++++
 make.js                     | 12 +++++--
 2 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/external/builder/builder.js b/external/builder/builder.js
index 4dc9f2655..864db8509 100644
--- a/external/builder/builder.js
+++ b/external/builder/builder.js
@@ -101,6 +101,66 @@ function preprocess(inFilename, outFilename, defines) {
 }
 exports.preprocess = preprocess;
 
+function preprocessCSS(mode, source, destination) {
+  function hasPrefixed(line) {
+    return (/(^|\W)-(ms|o|webkit)-\w/.test(line));
+  }
+
+  function removePrefixed(content) {
+    var lines = content.split(/\r?\n/g);
+    var i = 0;
+    while (i < lines.length) {
+      var line = lines[i];
+      if (!hasPrefixed(line)) {
+        i++;
+        continue;
+      }
+      if (/\{\s*$/.test(line)) {
+        var bracketLevel = 1;
+        var j = i + 1;
+        while (j < lines.length && bracketLevel > 0) {
+          var checkBracket = /([{}])\s*$/.exec(lines[j]);
+          if (checkBracket) {
+            if (checkBracket[1] === '{') {
+              bracketLevel++;
+            } else if (lines[j].indexOf('{') < 0) {
+              bracketLevel--;
+            }
+          }
+          j++;
+        }
+        lines.splice(i, j - i);
+      } else if (/[};]\s*$/.test(line)) {
+        lines.splice(i, 1);
+      } else {
+        // multiline? skipping until next directive or bracket
+        do {
+          lines.splice(i, 1);
+        } while (i < lines.length &&
+                 !/\}\s*$/.test(lines[i]) &&
+                 lines[i].indexOf(':') < 0);
+        if (i < lines.length && /\S\s*}\s*$/.test(lines[i])) {
+          lines[i] = lines[i].substr(lines[i].indexOf('}'));
+        }
+      }
+      // collapse whitespaces
+      while (lines[i] === '' && lines[i - 1] === '') {
+        lines.splice(i, 1);
+      }
+    }
+    return lines.join('\n');
+  }
+
+  if (mode !== 'firefox') {
+    throw new Error('Invalid CSS preprocessor mode');
+  }
+
+  var content = fs.readFileSync(source, 'utf8');
+  var out = removePrefixed(content);
+  fs.writeFileSync(destination, out);
+}
+exports.preprocessCSS = preprocessCSS;
+
 /**
  * Simplifies common build steps.
  * @param {object} setup
@@ -131,6 +191,13 @@ function build(setup) {
       preprocess(source, destWithFolder, defines);
     });
   });
+
+  (setup.preprocessCSS || []).forEach(function(option) {
+    var mode = option[0];
+    var source = option[1];
+    var destination = option[2];
+    preprocessCSS(mode, source, destination);
+  });
 }
 exports.build = build;
 
diff --git a/make.js b/make.js
index 7a5213368..1e6e8b007 100644
--- a/make.js
+++ b/make.js
@@ -70,8 +70,7 @@ target.all = function() {
 
 // Files that need to be included in every build.
 var COMMON_WEB_FILES =
-      ['web/viewer.css',
-       'web/images',
+      ['web/images',
        'web/debugger.js'],
     COMMON_WEB_FILES_PREPROCESS =
       ['web/viewer.js',
@@ -102,6 +101,7 @@ target.generic = function() {
     copy: [
       [COMMON_WEB_FILES, GENERIC_DIR + '/web'],
       ['external/webL10n/l10n.js', GENERIC_DIR + '/web'],
+      ['web/viewer.css', GENERIC_DIR + '/web'],
       ['web/compatibility.js', GENERIC_DIR + '/web'],
       ['web/compressed.tracemonkey-pldi-09.pdf', GENERIC_DIR + '/web'],
       ['web/locale', GENERIC_DIR + '/web']
@@ -410,6 +410,10 @@ target.firefox = function() {
       [COMMON_WEB_FILES_PREPROCESS, FIREFOX_BUILD_CONTENT_DIR + '/web'],
       [BUILD_TARGET, FIREFOX_BUILD_CONTENT_DIR + BUILD_TARGET],
       [SRC_DIR + 'network.js', FIREFOX_BUILD_CONTENT_DIR]
+    ],
+    preprocessCSS: [
+      ['firefox', 'web/viewer.css',
+       FIREFOX_BUILD_CONTENT_DIR + '/web/viewer.css']
     ]
   };
   builder.build(setup);
@@ -520,6 +524,9 @@ target.mozcentral = function() {
       [COMMON_WEB_FILES_PREPROCESS, MOZCENTRAL_CONTENT_DIR + '/web'],
       [BUILD_TARGET, MOZCENTRAL_CONTENT_DIR + BUILD_TARGET],
       [SRC_DIR + 'network.js', MOZCENTRAL_CONTENT_DIR]
+    ],
+    preprocessCSS: [
+      ['firefox', 'web/viewer.css', MOZCENTRAL_CONTENT_DIR + '/web/viewer.css']
     ]
   };
   builder.build(setup);
@@ -629,6 +636,7 @@ target.chrome = function() {
         'extensions/chrome/icon*.png',],
        CHROME_BUILD_DIR],
       ['external/webL10n/l10n.js', CHROME_BUILD_CONTENT_DIR + '/web'],
+      ['web/viewer.css', CHROME_BUILD_CONTENT_DIR + '/web'],
       ['web/locale', CHROME_BUILD_CONTENT_DIR + '/web']
     ],
     preprocess: [