搜索 
 设为首页 加入收藏
当前位置>>首页-学院-Python
来源: 作者: 日期:2009-03-20 05:03 网友评论:0条 点击:265
  Chrome扩展开发入门指南

     Google终于放出了Chrome的第一个扩展示例,虽然还十分简陋,但对喜欢扩展的firefox粉丝来说可说是个大好消息。

      准备工作:你需要使用a recent developer build 或者Google Chrome 2.0 beta.

      1)首先创建一个文件夹,例如c:"myextension,在这个目录下创建一个文本文件,命名为manifest.json,在其中放入下面几句:

{
  "format_version": 1,
  "id": "00123456789ABCDEF0123456789ABCDEF0123456",
  "version": "1.0",
  "name": "My First Extension",
  "description": "The first extension that I made."
}

其中各个参数含义如下:

format_version(必需的):向Chrome指明扩展所使用的清单格式版本。目前只有一个格式版本,因此设为1.

id(必需的):扩展的ID号(唯一的)。目前可以设为任何40个十进制数字,将来会改为扩展的公钥的SHA-1的哈希值。

version(必需的):扩展的版本号。可以使用任意点分格式的数字串

name(必需的):扩展的名称。

description(可选的):扩展的描述信息

      2)在目录下加入一个hello_world.html文件,在其中加入

    Hello,  World!

      3)为了让Chrome支持扩展,右键桌面上Chrome的快捷键,选择属性,在目标这一栏中空一格后,加入

--enable-extensions --load-extension="c:\myextension"

 

      4)启动Chrome,输入下列URL:

如图所示:

 

      5)输入下列URL:

chrome-ui://extensions/

将会列出所有已经安装的扩展,同时还会显示扩展系统启动时发生的错误信息。

 

6)内容脚本。它是由Chrome加载进来在web页面上运行的JavaScript文件。这和firefox扩展类似。要加入一个内容脚本,首先在清单文件中对其进行注册,如下所示:

{
  "format_version": 1,
  "id": "00123456789ABCDEF0123456789ABCDEF0123456",
  "version": "1.0",
  "name": "My First Extension",
  "description": "The first extension that I made.",
  "content_scripts": [
    {
      "matches": ["http://www.google.com/*"],
      "js": ["foo.js"]
    }
  ]
}

      然后创建一个脚本文件foo.js,其中代码如下:

document.images[0].src = "http://bit.ly/1293Af";
document.images[
0].style.height = "auto";

     在Chrome中输入http://www.google.com/,你将看到如下画面:

 

注:内容脚本可以在页面开头或结尾执行,默认情况下是结尾处执行,当然你也可以加入”run_at”:”document-start”来告诉Chrome在开头处执行。

7)NPAPI插件。Chrome扩展可以包含NPAPI插件这样的二进制组件。如果你想在扩展中使用一个NPAPI插件,首先在扩展中为其创建一个目录,名为”plugins”,然后在清单文件中为其注册如下:

{
  "format_version": 1,
  "id": "00123456789ABCDEF0123456789ABCDEF0123456",
  "version": "1.0",
  "name": "My First Extension",
  "description": "The first extension that I made.",
  "plugins_dir": "plugins"
}

8)打包发布。要对扩展进行打包发布前,首先确认你安装了Python2.6,然后使用下述脚本文件chromium_extension.py


#!/usr/bin/python
#
 Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
#
 Use of this source code is governed by a BSD-style license that can be
#
 found in the LICENSE file.

# chromium_extension.py

import array
import hashlib
import logging
import optparse
import os
import re
import shutil
import sys
import zipfile

if sys.version_info < (26):
  
import simplejson as json
else:
  
import json


ignore_dirs 
= [".svn""CVS"]
ignore_files 
= [re.compile(".*~")]

MANIFEST_FILENAME 
= "manifest.json"

class ExtensionDir:
  
def __init__(self, path):
    self._root 
= os.path.abspath(path)
    self._dirs 
= []
    self._files 
= []
    
for root, dirs, files in os.walk(path, topdown=True):
      
for dir in ignore_dirs:
        
if dir in dirs:
          dirs.remove(dir)
      root 
= os.path.abspath(root)
      
for dir in dirs:
        self._dirs.append(os.path.join(root, dir))
      
for f in files:
        
for match in ignore_files:
          
if not match.match(f):
            self._files.append(os.path.join(root, f))

  
def validate(self):
    
if os.path.join(self._root, MANIFEST_FILENAME) not in self._files:
      logging.error(
"package is missing a valid %s file" % MANIFEST_FILENAME)
      
return False
    
return True

  
def writeToPackage(self, path):
    
if not self.validate():
      
return False
    
try:
      f 
= open(os.path.join(self._root, MANIFEST_FILENAME))
      manifest 
= json.load(f)
      f.close()

      zip_path 
= path + ".zip"
      
if os.path.exists(zip_path):
        os.remove(zip_path)
      zip 
= zipfile.ZipFile(zip_path, "w")
      (root, dir) 
= os.path.split(self._root)
      root_len 
= len(self._root)
      
for file in self._files:
        arcname 
= file[root_len+1:]
        logging.debug(
"%s: %s" % (arcname, file))
        zip.write(file, arcname)
      zip.close()

      zip 
= open(zip_path, mode="rb")
      hash 
= hashlib.sha256()
      
while True:
        buf 
= zip.read(32 * 1024)
        
if not len(buf):
          
break
        hash.update(buf)
      zip.close()

      manifest[
"zip_hash"= hash.hexdigest()

      
# This is a bit odd - we're actually appending a new zip file to the end
      # of the manifest.  Believe it or not, this is actually an explicit
      # feature of the zip format, and many zip utilities (this library
      # and three others I tried) can still read the underlying zip file.
      if os.path.exists(path):
        os.remove(path)
      out 
= open(path, "wb")
      out.write(
"Cr24")  # Extension file magic number
      # The rest of the header is currently made up of three ints:
      # version, header size, manifest size
      header = array.array("l")
      header.append(
1)  # version
      header.append(16)  # header size
      manifest_json = json.dumps(manifest);
      header.append(len(manifest_json))  
# manifest size
      header.tofile(out)
      out.write(manifest_json);
      zip 
= open(zip_path, "rb")
      
while True:
        buf 
= zip.read(32 * 1024)
        
if not len(buf):
          
break
        out.write(buf)
      zip.close()
      out.close()

      os.remove(zip_path)

      logging.info(
"created extension package %s" % path)
    
except IOError, (errno, strerror):
      logging.error(
"error creating extension %s (%d, %s)" % (path, errno,
                    strerror))
      
try:
        
if os.path.exists(path):
          os.remove(path)
      
except:
        
pass
      
return False
    
return True


class ExtensionPackage:
  
def __init__(self, path):
    zip 
= zipfile.ZipFile(path)
    error 
= zip.testzip()
    
if error:
      logging.error(
"error reading extension: %s", error)
      
return
    logging.info(
"%s contents:" % path)
    files 
= zip.namelist()
    
for f in files:
      logging.info(f)


def Run():
  logging.basicConfig(level
=logging.INFO, format="[%(levelname)s] %(message)s")

  parser 
= optparse.OptionParser("usage: %prog --indir=<dir> --outfile=<file>")
  parser.add_option(
"""--indir",
                    help
="an input directory where the extension lives")
  parser.add_option(
"""--outfile",
                    help
="extension package filename to create")
  (options, args) 
= parser.parse_args()
  
if not options.indir:
    parser.error(
"missing required option --indir")
  
if not options.outfile:
    parser.error(
"missing required option --outfile")
  ext 
= ExtensionDir(options.indir)
  ext.writeToPackage(options.outfile)
  pkg 
= ExtensionPackage(options.outfile)
  
return 0


if __name__ == "__main__":
  retcode 
= Run()
  sys.exit(retcode)

 这个脚本运行方式如下所示:

chromium_extension.py --indir="c:\myextension" --outfile="myextension.crx"

这将会产生一个.crx文件,然后将其拖拽进Chrome即可实现扩展的安装

 

参考资料

1Chrome Extension HOWTO

2First Google Chrome Extensions


【发表评论 0条】
发表评论
最新评论:已有0位感兴趣的读者发表了看法

验证码:请输入前面图中的四位验证码,字母不区分大小写


网站简介 | 广告服务 | VIP资费标准 | 银行汇款帐号 | 网站地图 | 帮助 | 联系方式
地址:成都八宝街一号万和苑C座1203 电话:028-86272612 传真: 028-86272612
开源人网站版权所有  渝ICP备06004507号  建议使用1024*768分辨率