[Pkg-mozext-commits] [adblock-plus] 405/464: Added Safari support.

David Prévot taffit at moszumanska.debian.org
Tue Jul 22 20:44:38 UTC 2014


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository adblock-plus.

commit 74e9d9865fab33b9f3c73d5fa5b80807b128f131
Author: Sebastian Noack <sebastian at adblockplug.org>
Date:   Thu Oct 31 17:00:39 2013 +0100

    Added Safari support.
---
 Info.plist.tmpl      | 159 ++++++++++++++++++++++++++++++
 background.html.tmpl |   9 ++
 build.py             |  10 +-
 imageConversion.py   | 126 ++++++++++++++++++++++++
 manifest.json.tmpl   |   2 +-
 packager.py          |   9 ++
 packagerChrome.py    |  17 ++--
 packagerGecko.py     |   2 +
 packagerSafari.py    | 269 +++++++++++++++++++++++++++++++++++++++++++++++++++
 safariInfo.js.tmpl   |  32 ++++++
 10 files changed, 625 insertions(+), 10 deletions(-)

diff --git a/Info.plist.tmpl b/Info.plist.tmpl
new file mode 100644
index 0000000..d3308fb
--- /dev/null
+++ b/Info.plist.tmpl
@@ -0,0 +1,159 @@
+{%- macro str_or_real(value) -%}
+{%- if value is number -%}
+  <real>{{ value }}</real>
+{%- else -%}
+  <string>{{ value }}</string>
+{%- endif -%}
+{%- endmacro -%}
+
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+  <key>CFBundleDisplayName</key>
+  <string>{{ name }}</string>
+  <key>CFBundleIdentifier</key>
+  <string>org.adblockplus.{{ basename }}</string>
+  <key>CFBundleInfoDictionaryVersion</key>
+  <string>6.0</string>
+  <key>CFBundleShortVersionString</key>
+  <string>{{ shortVersion }}</string>
+  <key>CFBundleVersion</key>
+  <string>{{ version }}</string>
+  <key>Chrome</key>
+  <dict>
+    <key>Database Quota</key>
+    <real>104857600</real>
+    <key>Global Page</key>
+    <string>background.html</string>
+    {%- if menus %}
+    <key>Menus</key>
+    <array>
+      {%- for identifier, items in menus.iteritems() %}
+      <dict>
+        <key>Identifier</key>
+        <string>{{ identifier }}</string>
+        <key>Menu Items</key>
+        <array>
+          {%- for identifier, props in items.iteritems() %}
+          <dict>
+            <key>Identifier</key>
+            <string>{{ identifier }}</string>
+            {%- for key, value in props.iteritems() %}
+            <key>{{ key }}</key>
+            {{ str_or_real(value) }}
+            {%- endfor %}
+          </dict>
+          {%- endfor %}
+        </array>
+      </dict>
+      {%- endfor %}
+    </array>
+    {%- endif %}
+    {%- if popovers %}
+    <key>Popovers</key>
+    <array>
+      {%- for identifier, props in popovers.iteritems() %}
+      <dict>
+        <key>Identifier</key>
+        <string>{{ identifier }}</string>
+        {%- for key, value in props.iteritems() %}
+        <key>{{ key }}</key>
+        {{ str_or_real(value) }}
+        {%- endfor %}
+      </dict>
+      {%- endfor %}
+    </array>
+    {%- endif %}
+    {%- if toolbarItems %}
+    <key>Toolbar Items</key>
+    <array>
+      {%- for identifier, props in toolbarItems.iteritems() %}
+      <dict>
+        <key>Identifier</key>
+        <string>{{ identifier }}</string>
+        {%- for key, value in props.iteritems() %}
+        <key>{{ key }}</key>
+        {{ str_or_real(value) }}
+        {%- endfor %}
+      </dict>
+      {%- endfor %}
+    </array>
+    {%- endif %}
+  </dict>
+  {%- if startScripts or endScripts %}
+  <key>Content</key>
+  <dict>
+    <key>Scripts</key>
+    <dict>
+      {%- if startScripts %}
+      <key>Start</key>
+      <array>
+        {%- for script in startScripts %}
+        <string>{{ script }}</string>
+        {%- endfor %}
+      </array>
+      {%- endif %}
+      {%- if endScripts %}
+      <key>End</key>
+      <array>
+        {%- for script in endScripts %}
+        <string>{{ script }}</string>
+        {%- endfor %}
+      </array>
+      {%- endif %}
+    </dict>
+  </dict>
+  {%- endif %}
+  <key>ExtensionInfoDictionaryVersion</key>
+  <string>1.0</string>
+  <key>Permissions</key>
+  <dict>
+    <key>Website Access</key>
+    <dict>
+      {%- if allowedDomains and not allowAllDomains %}
+      <key>Allowed Domains</key>
+      <array>
+        {%- for domain in allowedDomains %}
+        <string>{{ domain }}</string>
+        {%- endfor %}
+      </array>
+      {%- endif %}
+      <key>Include Secure Pages</key>
+      {%- if allowSecurePages %}
+      <true/>
+      {%- else %}
+      <false/>
+      {%- endif %}
+      <key>Level</key>
+      {%- if allowAllDomains %}
+      <string>All</string>
+      {%- elif allowedDomains %}
+      <string>Some</string>
+      {%- else %}
+      <string>None</string>
+      {%- endif %}
+    </dict>
+  </dict>
+  <key>Description</key>
+  <string>{{ description }}</string>
+  {%- if author %}
+  <key>Author</key>
+  <string>{{ author }}</string>
+  {%- endif %}
+  {%- if homepage %}
+  <key>Website</key>
+  <string>{{ homepage }}</string>
+  {%- endif %}
+  {%- if not releaseBuild or updateURL %}
+  <key>Update Manifest URL</key>
+  <string>
+    {%- if not releaseBuild -%}
+      https://adblockplus.org/devbuilds/{{ basename }}/updates.plist
+    {%- else -%}
+      {{ updateURL }}
+    {%- endif -%}
+  </string>
+  {%- endif %}
+</dict>
+</plist>
diff --git a/background.html.tmpl b/background.html.tmpl
new file mode 100644
index 0000000..6dfa0a8
--- /dev/null
+++ b/background.html.tmpl
@@ -0,0 +1,9 @@
+<html>
+<head>
+{%- for script in backgroundScripts %}
+<script type="application/javascript" src="{{ script }}"></script>
+{%- endfor %}
+</head>
+<body>
+</body>
+</html>
diff --git a/build.py b/build.py
index 4db8f94..d87b4ad 100644
--- a/build.py
+++ b/build.py
@@ -18,7 +18,7 @@
 import os, sys, re, subprocess, buildtools
 from getopt import getopt, GetoptError
 
-knownTypes = ('gecko', 'chrome', 'opera')
+knownTypes = ('gecko', 'chrome', 'opera', 'safari')
 
 class Command(object):
   name = property(lambda self: self._name)
@@ -200,6 +200,10 @@ def runBuild(baseDir, scriptName, opts, args, type):
     packager.createBuild(baseDir, type=type, outFile=outFile, buildNum=buildNum,
                          releaseBuild=releaseBuild, keyFile=keyFile,
                          experimentalAPI=experimentalAPI)
+  elif type == 'safari':
+    import buildtools.packagerSafari as packager
+    packager.createBuild(baseDir, type=type, outFile=outFile, buildNum=buildNum,
+                         releaseBuild=releaseBuild, keyFile=keyFile)
 
 
 def runAutoInstall(baseDir, scriptName, opts, args, type):
@@ -425,11 +429,11 @@ with addCommand(runBuild, 'build') as command:
   command.params = '[options] [output_file]'
   command.addOption('Only include the given locales (if omitted: all locales not marked as incomplete)', short='l', long='locales', value='l1,l2,l3', types=('gecko'))
   command.addOption('Use given build number (if omitted the build number will be retrieved from Mercurial)', short='b', long='build', value='num')
-  command.addOption('File containing private key and certificates required to sign the package', short='k', long='key', value='file', types=('gecko', 'chrome', 'opera'))
+  command.addOption('File containing private key and certificates required to sign the package', short='k', long='key', value='file', types=('gecko', 'chrome', 'opera', 'safari'))
   command.addOption('Create a build for leak testing', short='m', long='multi-compartment', types=('gecko'))
   command.addOption('Create a release build', short='r', long='release')
   command.addOption('Enable use of experimental APIs', long='experimental')
-  command.supportedTypes = ('gecko', 'chrome', 'opera')
+  command.supportedTypes = ('gecko', 'chrome', 'opera', 'safari')
 
 with addCommand(runAutoInstall, 'autoinstall') as command:
   command.shortDescription = 'Install extension automatically'
diff --git a/imageConversion.py b/imageConversion.py
new file mode 100644
index 0000000..e360a9d
--- /dev/null
+++ b/imageConversion.py
@@ -0,0 +1,126 @@
+# coding: utf-8
+
+# This file is part of the Adblock Plus build tools,
+# Copyright (C) 2006-2013 Eyeo GmbH
+#
+# Adblock Plus is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 3 as
+# published by the Free Software Foundation.
+#
+# Adblock Plus is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import re
+from StringIO import StringIO
+
+import PIL.Image
+
+def get_alpha(image):
+  if image.mode in ('RGBA', 'LA'):
+    return image.split()[image.getbands().index('A')]
+
+  if image.mode == 'P':
+    transparency = image.info.get('transparency')
+
+    if transparency is not None:
+      table = [255] * 256
+      table[transparency] = 0
+
+      return image.point(table, 'L')
+
+def ensure_same_mode(im1, im2):
+  # if both images already have the same mode (and palette, in
+  # case of mode P), don't convert anything. Images with mode P,
+  # and a different palette, are the only case where images
+  # using the same mode, will be incompatible with each other.
+  if im1.mode == im2.mode and (im1.mode != 'P' or im1.getpalette() == im2.getpalette()):
+    return (im1, im2)
+
+  # if any given image has a mode that supports colors convert both
+  # images to RGB or RGBA, otherwise convert both images to L or LA.
+  # If any given image has an alpha channel (or mode P which
+  # can store transparent pixels too) convert both images
+  # to RGBA or LA, otherwise convert both images to RGB or L.
+  mode = max(
+    PIL.Image.getmodebase(im1.mode),
+    PIL.Image.getmodebase(im2.mode),
+
+    key=('L', 'RGB').index
+  )
+
+  if any(im.mode in ('RGBA', 'LA', 'P') for im in (im1, im2)):
+    mode += 'A'
+
+  return (
+    im1 if im1.mode == mode else im1.convert(mode),
+    im2 if im2.mode == mode else im2.convert(mode),
+  )
+
+def filter_grayscale(image, baseDir):
+  alpha = get_alpha(image)
+  image = image.convert('L')
+
+  if alpha:
+    image.putalpha(alpha)
+
+  return image
+
+def filter_contrastToAlpha(image, baseDir):
+  import PIL.ImageOps
+
+  alpha = PIL.Image.new('L', image.size, 255)
+  alpha.paste(image, mask=get_alpha(image))
+  alpha = PIL.ImageOps.invert(alpha)
+  alpha = PIL.ImageOps.autocontrast(alpha)
+
+  return PIL.Image.merge('LA', [PIL.Image.new('L', image.size), alpha])
+
+def filter_blend(image, baseDir, *args):
+  if len(args) == 2:
+    filename, opacity = args
+
+    overlay = PIL.Image.open(os.path.join(
+      baseDir,
+      *filename.split('/')
+    ))
+  else:
+    red, green, blue, opacity = args
+
+    overlay = PIL.Image.new('RGB', image.size, (
+      int(red),
+      int(green),
+      int(blue),
+    ))
+
+    # if the background image has an alpha channel copy it to
+    # the overlay, so that transparent areas stay transparent.
+    alpha = get_alpha(image)
+    if alpha:
+      overlay.putalpha(alpha)
+
+  image, overlay = ensure_same_mode(image, overlay)
+  return PIL.Image.blend(image, overlay, float(opacity))
+
+def convertImages(params, files):
+  metadata = params['metadata']
+
+  for filename, chain in metadata.items('convert_img'):
+    baseDir = os.path.dirname(metadata.option_source('convert_img', filename))
+    steps = re.split(r'\s*->\s*', chain)
+    image = PIL.Image.open(os.path.join(baseDir, *steps.pop(0).split('/')))
+
+    for step in steps:
+      filter, args = re.match(r'([^(]+)(?:\((.*)\))?', step).groups()
+      args = re.split(r'\s*,\s*', args) if args else ()
+      image = globals()['filter_' + filter](image, baseDir, *args)
+
+    f = StringIO()
+    f.name = filename
+    image.save(f)
+    files[filename] = f.getvalue()
diff --git a/manifest.json.tmpl b/manifest.json.tmpl
index 5aa4380..bfb8d0a 100644
--- a/manifest.json.tmpl
+++ b/manifest.json.tmpl
@@ -18,7 +18,7 @@
 {
   "manifest_version": 2,
   "name": "__MSG_name__{% if experimentalAPI %} experimental build{% endif %}",
-  "description": "__MSG_description__",
+  "description": "__MSG_description_{{ type }}__",
   "default_locale": "en_US",
   "version": {{version|json}},
 
diff --git a/packager.py b/packager.py
index 4fc1d08..2840935 100644
--- a/packager.py
+++ b/packager.py
@@ -113,6 +113,15 @@ class Files(dict):
       else:
         print >>sys.stderr, 'Warning: Mapped file %s doesn\'t exist' % source
 
+  def preprocess(self, filenames, params={}):
+    import jinja2
+    env = jinja2.Environment()
+
+    for filename in filenames:
+      env.autoescape = os.path.splitext(filename)[1].lower() in ('.html', '.xml')
+      template = env.from_string(self[filename].decode('utf-8'))
+      self[filename] = template.render(params).encode('utf-8')
+
   def zip(self, outFile, sortKey=None):
     zip = zipfile.ZipFile(outFile, 'w', zipfile.ZIP_DEFLATED)
     names = self.keys()
diff --git a/packagerChrome.py b/packagerChrome.py
index 6ace1db..6e4f827 100644
--- a/packagerChrome.py
+++ b/packagerChrome.py
@@ -34,7 +34,7 @@ def getIgnoredFiles(params):
   return result
 
 def getPackageFiles(params):
-  result = set(('_locales', 'icons', 'jquery-ui', 'lib', 'skin', 'ui',))
+  result = set(('_locales', 'icons', 'jquery-ui', 'lib', 'skin', 'ui', 'ext'))
 
   if params['devenv']:
     result.add('qunit')
@@ -279,11 +279,6 @@ def importGeckoLocales(params, files):
           files[operaFile] = files[chromeFile]
         del files[chromeFile]
 
-    # Hack: Replace "Chrome" by "Opera" in the locales
-    for path, data in files.iteritems():
-      if path.startswith("_locales/") and path.endswith("/messages.json"):
-        files[path] = re.sub(r"\bChrome\b", "Opera", data)
-
 def signBinary(zipdata, keyFile):
   import M2Crypto
   if not os.path.exists(keyFile):
@@ -335,6 +330,16 @@ def createBuild(baseDir, type='chrome', outFile=None, buildNum=None, releaseBuil
   if metadata.has_section('convert_js'):
     convertJS(params, files)
 
+  if metadata.has_section('convert_img'):
+    from imageConversion import convertImages
+    convertImages(params, files)
+
+  if metadata.has_section('preprocess'):
+    files.preprocess(
+      [f for f, _ in metadata.items('preprocess')],
+      {'needsExt': True}
+    )
+
   if metadata.has_section('import_locales'):
     importGeckoLocales(params, files)
 
diff --git a/packagerGecko.py b/packagerGecko.py
index 34b6c03..45c6fdf 100644
--- a/packagerGecko.py
+++ b/packagerGecko.py
@@ -329,6 +329,8 @@ def createBuild(baseDir, type="gecko", outFile=None, locales=None, buildNum=None
   fixupLocales(params, files)
   if not 'bootstrap.js' in files:
     addMissingFiles(params, files)
+  if metadata.has_section('preprocess'):
+    files.preprocess([f for f, _ in metadata.items('preprocess')])
   if keyFile:
     signFiles(files, keyFile)
   files.zip(outFile, sortKey=lambda x: '!' if x == 'META-INF/zigbert.rsa' else x)
diff --git a/packagerSafari.py b/packagerSafari.py
new file mode 100644
index 0000000..b2838e2
--- /dev/null
+++ b/packagerSafari.py
@@ -0,0 +1,269 @@
+# coding: utf-8
+
+# This file is part of the Adblock Plus build tools,
+# Copyright (C) 2006-2013 Eyeo GmbH
+#
+# Adblock Plus is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 3 as
+# published by the Free Software Foundation.
+#
+# Adblock Plus is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import re
+import json
+import ConfigParser
+from urlparse import urlparse
+
+from packager import readMetadata, getDefaultFileName, getBuildVersion, getTemplate, Files
+from packagerChrome import convertJS, importGeckoLocales, getIgnoredFiles, getPackageFiles, defaultLocale
+
+def processFile(path, data, params):
+  return data
+
+def createManifest(params, files):
+  template = getTemplate('Info.plist.tmpl', autoEscape=True)
+  metadata = params['metadata']
+  catalog = json.loads(files['_locales/%s/messages.json' % defaultLocale])
+
+  def parse_section(section, depth=1):
+    result = {}
+
+    if not metadata.has_section(section):
+      return result
+
+    for opt in metadata.options(section):
+      bits = opt.split('_', depth)
+      key = bits.pop().replace('_', ' ').title()
+      val = metadata.get(section, opt)
+
+      try:
+        val = int(val)
+      except ValueError:
+        try:
+          val = float(val)
+        except ValueError:
+          pass
+
+      reduce(lambda d, x: d.setdefault(x, {}), bits, result)[key] = val
+
+    return result
+
+  def get_optional(*args):
+    try:
+      return metadata.get(*args)
+    except ConfigParser.Error:
+      return None
+
+  allowedDomains = set()
+  allowAllDomains = False
+  allowSecurePages = False
+
+  for perm in metadata.get('general', 'permissions').split():
+    if perm == '<all_urls>':
+      allowAllDomains = True
+      allowSecurePages = True
+      continue
+
+    url = urlparse(perm)
+
+    if url.scheme == 'https':
+      allowSecurePages = True
+    elif url.scheme != 'http':
+      continue
+
+    if '*' in url.hostname:
+      allowAllDomains = True
+      continue
+
+    allowedDomains.add(url.hostname)
+
+  return template.render(
+    basename=metadata.get('general', 'basename'),
+    version=params['version'],
+    shortVersion=metadata.get('general', 'version'),
+    releaseBuild=params['releaseBuild'],
+    name=catalog['name']['message'],
+    description=catalog['description_safari']['message'],
+    author=get_optional('general', 'author'),
+    homepage=get_optional('general', 'homepage'),
+    updateURL=get_optional('general', 'updateURL'),
+    allowedDomains=allowedDomains,
+    allowAllDomains=allowAllDomains,
+    allowSecurePages=allowSecurePages,
+    startScripts=(get_optional('contentScripts', 'document_start') or '').split(),
+    endScripts=(get_optional('contentScripts', 'document_end') or '').split(),
+    menus=parse_section('menus', 2),
+    toolbarItems=parse_section('toolbar_items'),
+    popovers=parse_section('popovers')
+  ).encode('utf-8')
+
+def createBackgroundPage(params):
+  template = getTemplate('background.html.tmpl', autoEscape=True)
+  return template.render(
+    backgroundScripts=params['metadata'].get(
+      'general', 'backgroundScripts'
+    ).split()
+  ).encode('utf-8')
+
+def createInfoModule(params):
+  template = getTemplate('safariInfo.js.tmpl')
+  return template.render(params).encode('utf-8')
+
+def fixAbsoluteUrls(files):
+  for filename, content in files.iteritems():
+    if os.path.splitext(filename)[1].lower() == '.html':
+      files[filename] = re.sub(
+        r'(<[^<>]*?\b(?:href|src)\s*=\s*["\']?)\/+',
+        r'\1' + '/'.join(['..'] * filename.count('/') + ['']),
+        content, re.S | re.I
+      )
+
+def createSignedXarArchive(outFile, files, keyFile):
+  import subprocess
+  import tempfile
+  import shutil
+  import M2Crypto
+
+  # write files to temporary directory and create a xar archive
+  dirname = tempfile.mkdtemp()
+  try:
+    for filename, contents in files.iteritems():
+      path = os.path.join(dirname, filename)
+
+      try:
+        os.makedirs(os.path.dirname(path))
+      except OSError:
+        pass
+
+      with open(path, 'wb') as file:
+        file.write(contents)
+
+    subprocess.check_output(
+      ['xar', '-czf', os.path.abspath(outFile), '--distribution'] + os.listdir(dirname),
+      cwd=dirname
+    )
+  finally:
+    shutil.rmtree(dirname)
+
+  certificate_filenames = []
+  try:
+    # load key and certificates from the all-in-one key file
+    # and write each certificate in DER format to a seperate
+    # temporary file, that they can be passed to xar
+    bio = M2Crypto.BIO.openfile(keyFile)
+    try:
+      key = M2Crypto.RSA.load_key_bio(bio)
+
+      bio.reset()
+      while True:
+        try:
+          cert = M2Crypto.X509.load_cert_bio(bio)
+        except M2Crypto.X509.X509Error:
+          break
+
+        fd, filename = tempfile.mkstemp()
+        try:
+          certificate_filenames.append(filename)
+          os.write(fd, cert.as_der())
+        finally:
+          os.close(fd)
+    finally:
+      bio.close()
+
+    # add certificates and placeholder signature
+    # to the xar archive, and get data to sign
+    fd, digestinfo_filename = tempfile.mkstemp()
+    os.close(fd)
+    try:
+      subprocess.check_call(
+        [
+          'xar', '--sign', '-f', outFile,
+          '--digestinfo-to-sign', digestinfo_filename,
+          '--sig-size', str(len(key.private_encrypt('', M2Crypto.RSA.pkcs1_padding)))
+        ] + [
+          arg for cert in certificate_filenames for arg in ('--cert-loc', cert)
+        ]
+      )
+
+      with open(digestinfo_filename, 'rb') as file:
+        digestinfo = file.read()
+    finally:
+      os.unlink(digestinfo_filename)
+  finally:
+    for filename in certificate_filenames:
+      os.unlink(filename)
+
+  # sign data and inject signature into xar archive
+  fd, signature_filename = tempfile.mkstemp()
+  try:
+    try:
+      os.write(fd, key.private_encrypt(
+        digestinfo,
+        M2Crypto.RSA.pkcs1_padding
+      ))
+    finally:
+      os.close(fd)
+
+    subprocess.check_call(['xar', '--inject-sig', signature_filename, '-f', outFile])
+  finally:
+    os.unlink(signature_filename)
+
+def createBuild(baseDir, type, outFile=None, buildNum=None, releaseBuild=False, keyFile=None):
+  metadata = readMetadata(baseDir, type)
+  version = getBuildVersion(baseDir, metadata, releaseBuild, buildNum)
+
+  if not outFile:
+    outFile = getDefaultFileName(baseDir, metadata, version, 'safariextz' if keyFile else 'zip')
+
+  params = {
+    'type': type,
+    'baseDir': baseDir,
+    'releaseBuild': releaseBuild,
+    'version': version,
+    'devenv': False,
+    'metadata': metadata,
+  }
+
+  files = Files(getPackageFiles(params), getIgnoredFiles(params),
+                process=lambda path, data: processFile(path, data, params))
+  if metadata.has_section('mapping'):
+    files.readMappedFiles(metadata.items('mapping'))
+  files.read(baseDir)
+
+  if metadata.has_section('convert_js'):
+    convertJS(params, files)
+
+  if metadata.has_section('convert_img'):
+    from imageConversion import convertImages
+    convertImages(params, files)
+
+  if metadata.has_section('preprocess'):
+    files.preprocess(
+      [f for f, _ in metadata.items('preprocess')],
+      {'needsExt': True}
+    )
+
+  if metadata.has_section('import_locales'):
+    importGeckoLocales(params, files)
+
+  files['lib/info.js'] = createInfoModule(params)
+  files['background.html'] = createBackgroundPage(params)
+  files['Info.plist'] = createManifest(params, files)
+
+  fixAbsoluteUrls(files)
+
+  dirname = metadata.get('general', 'basename') + '.safariextension'
+  for filename in files.keys():
+    files[os.path.join(dirname, filename)] = files.pop(filename)
+
+  if keyFile:
+    createSignedXarArchive(outFile, files, keyFile)
+  else:
+    files.zip(outFile)
diff --git a/safariInfo.js.tmpl b/safariInfo.js.tmpl
new file mode 100644
index 0000000..638a6f2
--- /dev/null
+++ b/safariInfo.js.tmpl
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the Adblock Plus build tools,
+ * Copyright (C) 2006-2013 Eyeo GmbH
+ *
+ * Adblock Plus is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Adblock Plus is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+require.scopes.info = {
+  addonID: '',
+  addonName: {{ metadata.get('general', 'basename')|json }},
+  addonVersion: {{ version|json }},
+  addonRoot: '',
+
+  application: 'safari',
+  get applicationVersion() {
+    return navigator.userAgent.match(/Version\/([\d.]+)/)[1];
+  },
+  platform: 'safari',
+  get platformVersion() {
+    return this.applicationVersion;
+  }
+};

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/adblock-plus.git



More information about the Pkg-mozext-commits mailing list