creng 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+
3
+
4
+ #gem "rdf", "~> 0.3.10"
5
+ # Specify your gem's dependencies in creng.gemspec
6
+ gemspec
@@ -0,0 +1,42 @@
1
+ Creng 0.4.0
2
+ =====
3
+
4
+ ###Ruby gem for simple chrome extension development###
5
+
6
+ The aim of project to make development of chrome extensions more simple, giving to user time-tested tools and development patterns.
7
+ It includes last versions of following frameworks/libs:
8
+ * RequireJS
9
+ * Underscore.js
10
+ * jQuery
11
+ * Cajon
12
+
13
+
14
+ [Installation](https://github.com/traa/creng/wiki/Installation) | [Examples](https://github.com/traa/creng/wiki/Examples) | [Flags](https://github.com/traa/creng/wiki/Flags)
15
+
16
+
17
+
18
+ ### Usage ###
19
+
20
+ Project initialization
21
+ ------------
22
+ creng init <projectname>
23
+ This command creates dir with name of <projectname> and generates skeleton of application by creatin in it files, needed for first build of extension.
24
+ Also, it fetches last versions of libraries, needed to correct work of extension. So now, you can start your development in **dev** folder.
25
+
26
+
27
+
28
+ Project build
29
+ ------------
30
+ creng build
31
+ Must be executed in root folder of projectname. It builds entire project to **build** folder, executing following actions:
32
+ * Automatically managing frameworks dependencies (vendor/content folder frameworks will be added to content scripts in manifest file, vendor/background to background file (if it exists), vendor/ - to both)
33
+ * Auto-wrap code into define statements (no more same code constructions needed for work of RequireJS)
34
+ * Creng keeps an eye on "web_accessible_resources" for you (automatically manage it, so no more routine with writing all files)
35
+ * Easy background page management, just remove it and creng will build extension without it. Want to use [event](http://developer.chrome.com/extensions/event_pages.html) background page? Simply rename background_persistent.html to background.html and build it!
36
+ * Tracking of build version, auto-incrementation after every build x.x.x.buildversion
37
+ * Handling of options page, just create **options.html** in **html** folder to start working with it.
38
+ * Automatical handling of extension type. Just create **html/browser_action.html** for [browser action type](https://developer.chrome.com/extensions/browserAction.html), **html/page_action.html** for [page action type](http://developer.chrome.com/extensions/pageAction.html) or delete those files (if created) to switch for hidden type extension. Title of popup will be parsed from <title> tag in those html files
39
+ * Override new tab, bookmarks and history pages simply by creating html files with the same name (more at [examples page](https://github.com/traa/creng/wiki/Examples))
40
+ * Cut in build version marked blocks of code ( blocks marked with `//devblock_begin` and `//devblock_end`.
41
+ * Automatically removing all console.* calls in build.
42
+ * And more to come! It's just an early version of gem, so i plan to constantly increase number of features
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+
3
+
4
+ require 'creng'
5
+
6
+
7
+ module Creng
8
+ class CLI
9
+
10
+ def initialize(*args)
11
+
12
+ if args.empty?
13
+ puts 'no argument specified'
14
+ else
15
+ gen = Creng::Generator.new
16
+ gen.run args
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+ end
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+ Creng::CLI.new(*ARGV)
31
+
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "creng/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "creng"
7
+ s.version = Creng::VERSION
8
+ s.authors = ["Andrew Stepikov"]
9
+ s.email = ["stagedown@gmail.com"]
10
+ s.homepage = "http://markeeper.ru"
11
+ s.summary = %q{Create chrome extension with ease}
12
+ s.description = %q{Using this gem, you can create chrome extension skeleton with no troubles}
13
+
14
+ s.rubyforge_project = "creng"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ #s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.executables = ["creng"]
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency "rdf", "~> 0.3.10"
23
+
24
+ s.post_install_message = "This gem allows you to easily create, manage and develop your own chrome extension. For detailed information about usage type 'creng help'"
25
+
26
+ # specify any dependencies here; for example:
27
+ # s.add_development_dependency "rspec"
28
+ # s.add_runtime_dependency "rest-client"
29
+ end
@@ -0,0 +1,138 @@
1
+ #!/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require "creng/version"
5
+ require "fileutils"
6
+ require "rdf/cli"
7
+
8
+ module Creng
9
+
10
+ autoload :FileGenerator, 'creng/file_generator'
11
+ autoload :FileProcessor, 'creng/file_processor'
12
+ autoload :FileTweaker, 'creng/file_tweaker'
13
+ autoload :Feature, 'creng/feature'
14
+
15
+ autoload :ProcessJS, 'creng/files/processjs'
16
+ autoload :DaemonJS, 'creng/files/daemonjs'
17
+ autoload :ContentJS, 'creng/files/contentjs'
18
+ autoload :BackgroundJS, 'creng/files/backgroundjs'
19
+ autoload :RequestInspectorJS, 'creng/files/requestInspectorjs'
20
+
21
+ class Generator
22
+
23
+ def run(args)
24
+
25
+ options = {}
26
+ @optparser = RDF::CLI.options do
27
+ self.on('-n', '--nodefine', 'Init or build without define statements') do
28
+ options[:nodefine] = true
29
+ end
30
+
31
+ self.on('-c', '--noconsole', 'Build without debug messages(console.* calls)') do
32
+ options[:noconsole] = true
33
+ end
34
+
35
+ self.on('-b', '--withdevblock', 'Build and extension with blocks of code for development purposes') do
36
+ options[:withdevblock] = true
37
+ end
38
+
39
+ end
40
+ args = ARGV
41
+ @options = options
42
+
43
+ if !public_methods(false).map(&:to_s).include?(args[0])
44
+ puts "unknown command #{args.first}"
45
+ else
46
+ run_command(args) unless args.empty?
47
+ end
48
+ end
49
+
50
+ def run_command(args)
51
+ self.send(*args)
52
+ end
53
+
54
+ def debug
55
+ puts @projectname
56
+ end
57
+
58
+
59
+ def init(*args)
60
+ projectname = args.first
61
+ if File.directory? projectname
62
+ puts " project directory already exists"
63
+ else
64
+
65
+ puts " initialized project with name #{projectname}"
66
+
67
+ puts " create #{projectname}/dev/js/vendor/content"
68
+ FileUtils.mkdir_p "#{projectname}/dev/js/vendor/content"
69
+
70
+ puts " create #{projectname}/dev/js/vendor/utils"
71
+ FileUtils.mkdir_p "#{projectname}/dev/js/vendor/utils"
72
+
73
+ puts " create #{projectname}/dev/js/vendor/background"
74
+ FileUtils.mkdir_p "#{projectname}/dev/js/vendor/background"
75
+
76
+ puts " create #{projectname}/dev/images"
77
+ FileUtils.mkdir_p "#{projectname}/dev/images"
78
+
79
+ puts " create #{projectname}/dev/html"
80
+ FileUtils.mkdir_p "#{projectname}/dev/html"
81
+
82
+ puts " create #{projectname}/dev/js"
83
+ FileUtils.mkdir_p "#{projectname}/dev/js/"
84
+
85
+ puts " create #{projectname}/build"
86
+ FileUtils.mkdir_p "#{projectname}/build"
87
+
88
+ FileGenerator.new projectname
89
+
90
+
91
+ end
92
+ end
93
+
94
+
95
+
96
+ def build
97
+
98
+ FileProcessor.inProjectDir do |curdir|
99
+ FileProcessor.process curdir, @options, FileGenerator.getAccessibleResources()
100
+ end
101
+
102
+ end
103
+
104
+
105
+ def feature(*args)
106
+ action = args.first
107
+ value = args[1]
108
+
109
+ if Feature.respond_to? action
110
+
111
+ FileProcessor.inProjectDir do |curdir|
112
+
113
+ Feature.send(action, curdir, value)
114
+ end
115
+
116
+
117
+ else
118
+ puts "feature action not supported"
119
+ end
120
+
121
+
122
+ end
123
+
124
+
125
+ def help(command = nil)
126
+ puts @optparser
127
+ #puts @options
128
+ puts
129
+ puts "Commands:"
130
+ puts " help Shows this help."
131
+ puts " init <project_name> Initialize new project"
132
+ puts " build <project_name> building project with given options"
133
+ puts " feature <add|remove> adding or removing feature to/from project"
134
+ end
135
+
136
+
137
+ end
138
+ end
@@ -0,0 +1,49 @@
1
+
2
+
3
+ module Creng
4
+
5
+ class Feature
6
+
7
+ def self.add projectpath, value
8
+
9
+ if Feature.respond_to? "add#{value.capitalize}"
10
+ Feature.send("add#{value.capitalize}", projectpath)
11
+ else
12
+ puts "unsupported feature"
13
+ end
14
+
15
+ end
16
+
17
+
18
+ def self.addWebrequest projectpath
19
+
20
+ puts " adding webrequest feature to dev project"
21
+
22
+ manifest_text = File.read("#{projectpath}/dev/manifest.json")
23
+
24
+ manifest_text = manifest_text.gsub(/(\"webRequest\"\,?\n?|\"webRequestBlocking\"\,?\n?)/, "")
25
+
26
+ manifest_text = manifest_text.gsub(Regexp.new('\"permissions\"\s*\:\s*\[(.*?)\]', Regexp::MULTILINE)) { |m| m.gsub!($1, "\n\"webRequest\",\n\"webRequestBlocking\",#{$1}") }
27
+
28
+ puts " checking manifest.json"
29
+
30
+ File.open("#{projectpath}/dev/manifest.json", 'w') do |f|
31
+ f.write manifest_text
32
+ end
33
+
34
+ FileGenerator.generateWebrequest projectpath
35
+
36
+ puts " now you can simply include requestInspector file in your background scripts"
37
+ puts " "
38
+ puts " ======================================================================="
39
+ puts " var inspector = require(\"./requestInspector\").requestInspector;"
40
+ puts " inspector.start();"
41
+ puts " ======================================================================="
42
+
43
+ end
44
+
45
+
46
+
47
+ end
48
+
49
+ end
@@ -0,0 +1,245 @@
1
+
2
+
3
+ module Creng
4
+
5
+ class FileGenerator
6
+
7
+
8
+
9
+ def initialize projectname
10
+
11
+ @projectname = projectname
12
+ generate
13
+ end
14
+
15
+
16
+ def self.getAccessibleResources projectname = nil
17
+
18
+ if projectname.nil?
19
+ allfiles = Dir["build/**/*"]
20
+ regex = Regexp.new("^build\/")
21
+ else
22
+ allfiles = Dir["#{projectname}/build/**/*"]
23
+ regex = Regexp.new("^#{projectname}\/build\/")
24
+ end
25
+
26
+ #allfiles = projectname.nil? ? Dir["dev/**/*"] : Dir["#{projectname}/dev/**/*"]
27
+
28
+
29
+
30
+ #puts "allfiles #{allfiles}, #{projectname}"
31
+ accessible_resources = []
32
+
33
+ allfiles.each do |file|
34
+ unless File.directory? file
35
+ if File.basename(file) != 'manifest.json'
36
+ accessible_resources.push(file.gsub(regex, ""))
37
+ end
38
+ end
39
+ end
40
+
41
+ accessible_resources
42
+ end
43
+
44
+
45
+
46
+ def generateManifest
47
+
48
+ accessible_resources = FileGenerator.getAccessibleResources(@projectname)
49
+
50
+ File.open("#{@projectname}/dev/manifest.json", 'w') do |f|
51
+ f.write <<-"...".gsub!(/^ {20}/, '')
52
+ {
53
+ "name": "#{@projectname}",
54
+ "version": "0.0.1.0",
55
+ "manifest_version": 2,
56
+ "description": "Sample extension generated by Creng ruby gem",
57
+ "icons": {
58
+ "16": "images/extension-16x16.png",
59
+ "48": "images/extension-48x48.png",
60
+ "128": "images/extension-64x64.png"
61
+ },
62
+ "background": {
63
+ "page" : "html/background.html",
64
+ "persistent": true
65
+ },
66
+ "permissions": [
67
+ "webRequest",
68
+ "webRequestBlocking",
69
+ "tabs",
70
+ "*://*/*"
71
+ ],
72
+ "content_scripts": [
73
+ {
74
+ "matches": ["*://*/*"],
75
+ "js": [
76
+ "js/vendor/cajon.js",
77
+ "js/vendor/jquery.min.js",
78
+ "js/vendor/underscore.min.js",
79
+ "js/process.js"
80
+ ],
81
+ "run_at": "document_start"
82
+ }
83
+ ],
84
+ "web_accessible_resources": #{accessible_resources}
85
+ }
86
+ ...
87
+ end
88
+
89
+ end
90
+
91
+ #point of enter
92
+ def generate
93
+
94
+ generateJS([ProcessJS.new, ContentJS.new, BackgroundJS.new, DaemonJS.new])
95
+
96
+ fetchLibs
97
+ generateHTML
98
+ fetchImages
99
+ generateManifest
100
+ puts " create #{@projectname}/dev/manifest.json"
101
+ end
102
+
103
+
104
+ def generateJS filearray
105
+
106
+ filearray.each do |file|
107
+
108
+ File.open("#{@projectname}/dev/#{file.path}/#{file.name}", 'w') do |f|
109
+ f.write file.contents
110
+ end
111
+ puts " create #{@projectname}/dev/#{file.path}/#{file.name}"
112
+
113
+ end
114
+
115
+
116
+
117
+
118
+ end
119
+
120
+
121
+ def fetchLibs
122
+
123
+ require 'open-uri'
124
+
125
+ #####################
126
+ # Cajon
127
+ #####################
128
+ File.open("#{@projectname}/dev/js/vendor/content/cajon.js", 'w') do |f|
129
+
130
+ open("https://raw.github.com/requirejs/cajon/master/cajon.js", 'rb') do |read_file|
131
+ f.write(read_file.read)
132
+ end
133
+
134
+ end
135
+ puts " fetching cajon.js from https://github.com/requirejs/cajon"
136
+
137
+ #####################
138
+ # Jquery
139
+ #####################
140
+ File.open("#{@projectname}/dev/js/vendor/content/jquery.min.js", 'w') do |f|
141
+
142
+ open("http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js", 'rb') do |read_file|
143
+ f.write(read_file.read)
144
+ end
145
+
146
+ end
147
+ puts " fetching jQuery from Google CDN"
148
+
149
+ #####################
150
+ # Underscore
151
+ #####################
152
+ File.open("#{@projectname}/dev/js/vendor/underscore.min.js", 'w') do |f|
153
+
154
+ open("https://raw.github.com/documentcloud/underscore/master/underscore-min.js", 'rb') do |read_file|
155
+ f.write(read_file.read)
156
+ end
157
+
158
+ end
159
+ puts " fetching underscore.js from https://github.com/documentcloud/underscore"
160
+
161
+ #####################
162
+ # RequireJS
163
+ #####################
164
+ File.open("#{@projectname}/dev/js/vendor/background/require.js", 'w') do |f|
165
+
166
+ open("https://raw.github.com/jrburke/requirejs/master/require.js", 'rb') do |read_file|
167
+ f.write(read_file.read)
168
+ end
169
+
170
+ end
171
+ puts " fetching requirejs from https://github.com/jrburke/requirejs"
172
+
173
+
174
+ end
175
+
176
+
177
+ def fetchImages
178
+ #fetching sample extension icons from github
179
+ File.open("#{@projectname}/dev/images/extension-16x16.png", 'w') do |f|
180
+ open("https://raw.github.com/traa/creng/master/lib/creng/vendor/images/extension-16x16.png", 'rb') do |read_file|
181
+ f.write(read_file.read)
182
+ end
183
+ end
184
+ puts " fetching extension icon 16x16 from https://github.com/traa/creng"
185
+
186
+ File.open("#{@projectname}/dev/images/extension-48x48.png", 'w') do |f|
187
+ open("https://raw.github.com/traa/creng/master/lib/creng/vendor/images/extension-48x48.png", 'rb') do |read_file|
188
+ f.write(read_file.read)
189
+ end
190
+ end
191
+ puts " fetching extension icon 48x48 from https://github.com/traa/creng"
192
+
193
+ File.open("#{@projectname}/dev/images/extension-64x64.png", 'w') do |f|
194
+ open("https://raw.github.com/traa/creng/master/lib/creng/vendor/images/extension-64x64.png", 'rb') do |read_file|
195
+ f.write(read_file.read)
196
+ end
197
+ end
198
+ puts " fetching extension icon 64x64 from https://github.com/traa/creng"
199
+ end
200
+
201
+
202
+ def generateHTML
203
+
204
+ File.open("#{@projectname}/dev/html/background_persistent.html", 'w') do |f|
205
+
206
+ f.write <<-"...".gsub!(/^ {20}/, '')
207
+ <!doctype html>
208
+ <html>
209
+ <head>
210
+ </head>
211
+
212
+ <body>
213
+ <center><h1>BACKGROUND PAGE</h1></center>
214
+ </body>
215
+
216
+
217
+ </html>
218
+ ...
219
+
220
+ end
221
+ puts " create #{@projectname}/dev/html/background_persistent.html"
222
+
223
+ end
224
+
225
+
226
+ def self.generateWebrequest projectpath
227
+
228
+ requestInspectorFile = RequestInspectorJS.new
229
+
230
+ unless File.file? "#{projectpath}/dev/#{requestInspectorFile.path}/#{requestInspectorFile.name}"
231
+
232
+ File.open("#{projectpath}/dev/#{requestInspectorFile.path}/#{requestInspectorFile.name}", 'w') do |f|
233
+ f.write requestInspectorFile.contents
234
+ end
235
+ puts " create #{projectpath}/dev/#{requestInspectorFile.path}/#{requestInspectorFile.name}"
236
+
237
+ else
238
+ puts " requestInspector already exists"
239
+ end
240
+
241
+ end
242
+
243
+ end
244
+
245
+ end
@@ -0,0 +1,380 @@
1
+ require 'digest/md5'
2
+
3
+ module Creng
4
+
5
+ class FileProcessor
6
+
7
+
8
+
9
+ def self.process(clean_path, options, accessible_resources)
10
+
11
+ FileUtils.remove_dir "#{clean_path}/build"
12
+
13
+ #raising build version
14
+ FileProcessor.raiseDevBuildVersion clean_path
15
+
16
+ FileUtils.copy_entry "#{clean_path}/dev", "#{clean_path}/build", false, true
17
+
18
+
19
+
20
+
21
+ files = Dir["#{clean_path}/dev/js/*.js"]
22
+
23
+ files.each do |file|
24
+
25
+ #WORKING WITH ALL JS FILES (EXCEPT SUB DIRS)
26
+ text = File.read(file)
27
+ text_hash = Digest::MD5.hexdigest text
28
+
29
+ filename = File.basename(file)
30
+
31
+ #can be turned off with flag --withdevblock
32
+ if !options[:withdevblock]
33
+
34
+ #cutting blocks of code, which marked as "code for development version only"
35
+ text = FileTweaker.cutDevBlock text
36
+
37
+ end
38
+
39
+ #build without console.* calls
40
+ if options[:noconsole]
41
+
42
+ text = FileTweaker.cutDebugMessages text
43
+
44
+ end
45
+
46
+ exclusions_from_defining = ['process.js', 'daemon.js']
47
+
48
+ clean_path_for_regex = clean_path.gsub(/\//, '\/')
49
+
50
+ buildpath = file.gsub(Regexp.new("#{clean_path_for_regex}\/dev"), "#{clean_path}/build")
51
+
52
+ #if define is allowed
53
+ if !options[:nodefine]
54
+ unless exclusions_from_defining.include? filename
55
+ text = "#{FileProcessor.preDefine}#{text}#{FileProcessor.postDefine}"
56
+
57
+ end
58
+ end
59
+ #endof if define allowed
60
+
61
+ #only if file text was changed
62
+ if text_hash != (Digest::MD5.hexdigest(text))
63
+
64
+ File.open(buildpath, 'w') do |f|
65
+ f.write text
66
+ end
67
+
68
+ puts " processed js/#{filename}"
69
+ end
70
+
71
+
72
+
73
+
74
+ end
75
+ #endof files loop
76
+
77
+ FileProcessor.processManifest clean_path, accessible_resources do |manifest_text, accessible_resources_new|
78
+ #changing web_accessible_resources array
79
+ manifest_text = manifest_text.gsub(/(\"web_accessible_resources\")\s?\:\s?(\[.*\])/, "\"web_accessible_resources\": [#{accessible_resources_new.join(',')}]")
80
+ #changing background object
81
+ manifest_text = FileProcessor.processBackgroundPage clean_path, manifest_text
82
+ #checking js/vendor dir
83
+ manifest_text = FileProcessor.processFrameworks clean_path, manifest_text
84
+ #checking options page
85
+ manifest_text = FileProcessor.processOptionsPage clean_path, manifest_text
86
+ #checking browser_action or page_action pages
87
+ manifest_text = FileProcessor.processExtensionType clean_path, manifest_text
88
+ #checks for overrided history, bookmarks and new tab pages
89
+ manifest_text = FileProcessor.processOverrideInternalPages clean_path, manifest_text
90
+
91
+
92
+
93
+
94
+ end
95
+
96
+
97
+
98
+ end
99
+
100
+
101
+ def self.preDefine
102
+ <<-"...".gsub!(/^ {12}/, '')
103
+ define(function(require) { exports = {};
104
+ (function() {
105
+ ...
106
+ end
107
+
108
+
109
+ def self.postDefine
110
+ <<-"...".gsub!(/^ {12}/, '')
111
+ }).call(this);
112
+ return exports;});
113
+ ...
114
+ end
115
+
116
+ #type: browser_action or page_action
117
+ def self.ActionTemplate type, title
118
+
119
+ <<-"...".gsub!(/^ {3}/, '')
120
+ "#{type}": {
121
+ "default_icon": {
122
+ "19": "images/extension-48x48.png",
123
+ "38": "images/extension-48x48.png"
124
+ },
125
+ "default_title": "#{title}",
126
+ "default_popup": "#{type}.html"
127
+ }
128
+ ...
129
+
130
+ end
131
+
132
+
133
+ def self.inProjectDir
134
+
135
+ curdir = Dir.pwd
136
+
137
+ if (['dev', 'build'] & Dir.entries(curdir).select { |file| File.directory? File.join(curdir, file)}).length == 2
138
+ yield curdir if block_given?
139
+ else
140
+ puts "you must be in project directory"
141
+ end
142
+
143
+ end
144
+
145
+
146
+
147
+ def self.processBackgroundPage path, manifest_text
148
+
149
+ if File.file? "#{path}/build/html/background.html"
150
+ background_page = "#{path}/build/html/background.html"
151
+ background_persistent = false
152
+ elsif File.file? "#{path}/build/html/background_persistent.html"
153
+ background_page = "#{path}/build/html/background_persistent.html"
154
+ #renaming to default
155
+ File.rename background_page, "#{path}/build/html/background.html"
156
+ background_persistent = true
157
+ else
158
+ background_page = nil
159
+ background_persistent = nil
160
+ end
161
+
162
+ unless background_page.nil?
163
+ manifest_text = manifest_text.gsub(/(\"persistent\")\s?\:\s?(true|false)/, "\"persistent\": #{background_persistent}")
164
+ else
165
+ manifest_text = manifest_text.gsub(/(\"background\")\s?\:\s?(\{(.|\n)*\}\,)/, "")
166
+
167
+ end
168
+
169
+
170
+ puts " processed html/background.html"
171
+ manifest_text
172
+
173
+ end
174
+
175
+
176
+ def self.processManifest clean_path, accessible_resources
177
+
178
+ manifest_text = File.read("#{clean_path}/build/manifest.json")
179
+
180
+ accessible_resources_new = []
181
+
182
+ accessible_resources.each do |res|
183
+ accessible_resources_new.push("\"#{res}\"")
184
+ end
185
+
186
+ manifest_text = yield(manifest_text, accessible_resources_new) if block_given?
187
+
188
+ File.open("#{clean_path}/build/manifest.json", 'w') do |f|
189
+ f.write manifest_text
190
+ end
191
+
192
+ puts " processed manifest.json"
193
+
194
+ end
195
+
196
+
197
+ def self.processFrameworks clean_path, manifest_text
198
+
199
+ background_files = Dir["#{clean_path}/build/js/vendor/background/*.js"]
200
+ content_files = Dir["#{clean_path}/build/js/vendor/content/*.js"]
201
+ both_files = Dir["#{clean_path}/build/js/vendor/*.js"]
202
+
203
+
204
+ content_pool = ["\"js/process.js\""]
205
+ background_pool = []
206
+
207
+
208
+ background_files.each do |file|
209
+ if File.file? file
210
+ background_pool.push "<script type='text/javascript' src='js/vendor/#{File.basename file}'></script>"
211
+ end
212
+ end
213
+ FileUtils.mv background_files, "#{clean_path}/build/js/vendor"
214
+
215
+
216
+ content_files.each do |file|
217
+ if File.file? file
218
+ content_pool.push "\"js/vendor/#{File.basename file}\""
219
+ end
220
+ end
221
+ FileUtils.mv content_files, "#{clean_path}/build/js/vendor"
222
+
223
+ both_files.each do |file|
224
+ if File.file? file
225
+ content_pool.push "\"js/vendor/#{File.basename file}\""
226
+ background_pool.push "<script type='text/javascript' src='js/vendor/#{File.basename file}'></script>"
227
+ end
228
+ end
229
+
230
+ FileUtils.remove_dir "#{clean_path}/build/js/vendor/content"
231
+ FileUtils.remove_dir "#{clean_path}/build/js/vendor/background"
232
+
233
+
234
+ #replacing for content scripts loaded frameworks
235
+ if content_pool.length
236
+ manifest_text = manifest_text.gsub(/\"content_scripts\"\s*\:\s*?(?:.|\n)*\"js\"\s?\:\s*(\[(?:.|\n)*?\])/) { |m| m.gsub!($1, "[#{content_pool.join(',')}]") }
237
+ end
238
+
239
+ #@TODO: background page logic handling (insert script tags into html)
240
+ if background_pool.length
241
+ FileProcessor.changeBackgroundPage clean_path, background_pool
242
+ end
243
+
244
+
245
+
246
+ manifest_text
247
+
248
+ end
249
+
250
+
251
+ def self.changeBackgroundPage clean_path, background_pool
252
+
253
+ background_page_path = "#{clean_path}/build/html/background.html"
254
+
255
+ background_page_text = File.read(background_page_path)
256
+
257
+ background_page_text = background_page_text.gsub(/\<\/head\>/,"#{background_pool.join(' ')}</head>")
258
+
259
+ File.open(background_page_path, 'w') do |f|
260
+ f.write background_page_text
261
+ end
262
+
263
+ end
264
+
265
+
266
+ def self.processOptionsPage clean_path, manifest_text
267
+
268
+ options_page_path = "#{clean_path}/build/html/options.html"
269
+
270
+ if File.file? options_page_path
271
+ manifest_text = manifest_text.gsub(/\"manifest_version\"\s*\:\s*2\s*\,/, "\"manifest_text\": 2,\n \"options_page\": \"html/options.html\",")
272
+ puts " processed html/options.html"
273
+ else
274
+ manifest_text = manifest_text.gsub(/\"options_page\"\s*\:\s*\"html\/options\.html\"\,/, "")
275
+ puts " processed options page removing"
276
+ end
277
+
278
+
279
+ manifest_text
280
+ end
281
+
282
+ def self.processExtensionType clean_path, manifest_text
283
+
284
+ browser_action_page_path = "#{clean_path}/build/html/browser_action.html"
285
+ page_action_page_path = "#{clean_path}/build/html/page_action.html"
286
+
287
+
288
+ type = nil
289
+
290
+ manifest_text = manifest_text.gsub(/\,?\n?\"page_action\"\s*\:\s*\{(.|\n)*\}\,?/, "")
291
+ manifest_text = manifest_text.gsub(/\,?\n?\"browser_action\"\s*\:\s*\{(.|\n)*\}\,?/, "")
292
+
293
+ if File.file? browser_action_page_path
294
+ type = "browser_action"
295
+ elsif File.file? page_action_page_path
296
+ type = "page_action"
297
+ end
298
+
299
+
300
+
301
+ unless type.nil?
302
+ page_text = File.read("#{clean_path}/build/html/#{type}.html")
303
+
304
+ title = page_text.match(/\<title\>(.*)\<\/title\>/)[1]
305
+ title = title.nil? ? "Action Title" : title
306
+ action_text = FileProcessor.ActionTemplate type, title
307
+
308
+
309
+ manifest_text = manifest_text.gsub(/(\n){1}(\})$/) { |m| m.gsub!($1, ",\n#{action_text}") }
310
+ end
311
+
312
+ manifest_text
313
+
314
+ end
315
+
316
+
317
+ def self.processOverrideInternalPages clean_path, manifest_text
318
+
319
+ override_tab_page = "override_tab.html"
320
+ override_history_page = "override_history.html"
321
+ override_bookmarks_page = "override_bookmarks.html"
322
+
323
+ manifest_text = manifest_text.gsub(/\"chrome_url_overrides\"\s*\:\s*\{(.|\n)*\}\,/, "")
324
+ overriden_pages = []
325
+
326
+
327
+ if File.file? "#{clean_path}/dev/html/#{override_tab_page}"
328
+ overriden_pages.push("\"newtab\": \"#{override_tab_page}\"")
329
+ end
330
+
331
+ if File.file? "#{clean_path}/dev/html/#{override_history_page}"
332
+ overriden_pages.push("\"history\": \"#{override_history_page}\"")
333
+ end
334
+
335
+ if File.file? "#{clean_path}/dev/html/#{override_bookmarks_page}"
336
+ overriden_pages.push("\"bookmarks\": \"#{override_bookmarks_page}\"")
337
+ end
338
+
339
+ if overriden_pages.length > 0
340
+ overriden_pages_list = overriden_pages.join(" ,\n")
341
+ overriden_pages_string = "\"chrome_url_overrides\": {\n#{overriden_pages_list}\n}"
342
+ manifest_text = manifest_text.gsub(/(\n){1}(\})$/) { |m| m.gsub!($1, ",\n#{overriden_pages_string}\n") }
343
+
344
+ end
345
+
346
+ puts " processing overriden pages"
347
+
348
+ manifest_text
349
+
350
+ end
351
+
352
+
353
+ def self.raiseDevBuildVersion clean_path
354
+
355
+ manifest_dev_path = "#{clean_path}/dev/manifest.json"
356
+ manifest_text = File.read(manifest_dev_path)
357
+
358
+ manifest_text = manifest_text.gsub(/\"version\"\s*\:\s*\"(.*)\"\,/) {
359
+
360
+ |text|
361
+ digits = $1.split '.'
362
+ buildversion = digits[3].to_i + 1
363
+ new_version = "#{digits[0]}.#{digits[1]}.#{digits[2]}.#{buildversion}"
364
+
365
+ text.gsub($1, "#{new_version}")
366
+
367
+ }
368
+
369
+ File.open(manifest_dev_path, 'w') do |f|
370
+ f.write manifest_text
371
+ end
372
+
373
+ end
374
+
375
+
376
+
377
+
378
+ end
379
+
380
+ end
@@ -0,0 +1,32 @@
1
+ module Creng
2
+
3
+ class FileTweaker
4
+
5
+ #cutting blocks of code, marked as ###devblock_begin and ###devblock_end
6
+ #returns modified text of file
7
+ def self.cutDevBlock text
8
+
9
+ text = text.gsub(/\/\/devblock_begin(.|\n)*?\/\/devblock_end/, "")
10
+
11
+ text
12
+ end
13
+
14
+
15
+ #cutting all console.* calls
16
+ def self.cutDebugMessages text
17
+
18
+ text = text.gsub(/console\..*?\(.*\)(\;)?/, "")
19
+
20
+ text
21
+
22
+ end
23
+
24
+ def self.manifestTweak
25
+
26
+
27
+
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,30 @@
1
+
2
+ module Creng
3
+
4
+ class BackgroundJS < FileGenerator
5
+
6
+ attr_reader :name
7
+ attr_reader :path
8
+ attr_reader :contents
9
+
10
+ def initialize
11
+ @name = 'background.js'
12
+ @path = 'js'
13
+ end
14
+
15
+ def create
16
+ puts "called create of #{@filename}"
17
+ end
18
+
19
+ def contents
20
+ <<-"...".gsub!(/^ {16}/, '')
21
+ console.log("background script of my extension is running!");
22
+ ...
23
+ end
24
+
25
+
26
+
27
+ end
28
+
29
+
30
+ end
@@ -0,0 +1,30 @@
1
+
2
+ module Creng
3
+
4
+ class ContentJS < FileGenerator
5
+
6
+ attr_reader :name
7
+ attr_reader :path
8
+ attr_reader :contents
9
+
10
+ def initialize
11
+ @name = 'content.js'
12
+ @path = 'js'
13
+ end
14
+
15
+ def create
16
+ puts "called create of #{@filename}"
17
+ end
18
+
19
+ def contents
20
+ <<-"...".gsub!(/^ {16}/, '')
21
+ console.log("content of my extension running!");
22
+ ...
23
+ end
24
+
25
+
26
+
27
+ end
28
+
29
+
30
+ end
@@ -0,0 +1,41 @@
1
+
2
+ module Creng
3
+
4
+ class DaemonJS < FileGenerator
5
+
6
+ attr_reader :name
7
+ attr_reader :path
8
+ attr_reader :contents
9
+
10
+ def initialize
11
+ @name = 'daemon.js'
12
+ @path = 'js'
13
+ end
14
+
15
+ def create
16
+ puts "called create of #{@filename}"
17
+ end
18
+
19
+ def contents
20
+
21
+ <<-"...".gsub!(/^ {16}/, '')
22
+ require.config({
23
+ baseUrl: '/js'
24
+ });
25
+
26
+
27
+ require([
28
+ "background"
29
+ ], function() {
30
+
31
+ });
32
+
33
+ ...
34
+ end
35
+
36
+
37
+
38
+ end
39
+
40
+
41
+ end
@@ -0,0 +1,41 @@
1
+
2
+ module Creng
3
+
4
+ class ProcessJS < FileGenerator
5
+
6
+ attr_reader :name
7
+ attr_reader :path
8
+ attr_reader :contents
9
+
10
+ def initialize
11
+ @name = 'process.js'
12
+ @path = 'js'
13
+ end
14
+
15
+ def create
16
+ puts "called create of #{@filename}"
17
+ end
18
+
19
+ def contents
20
+
21
+ <<-"...".gsub!(/^ {16}/, '')
22
+ require.config({
23
+ baseUrl: chrome.extension.getURL('/js')
24
+ });
25
+
26
+
27
+ require([
28
+ "content"
29
+ ], function() {
30
+
31
+ });
32
+ ...
33
+
34
+ end
35
+
36
+
37
+
38
+ end
39
+
40
+
41
+ end
@@ -0,0 +1,50 @@
1
+
2
+ module Creng
3
+
4
+ class RequestInspectorJS < FileGenerator
5
+
6
+ attr_reader :name
7
+ attr_reader :path
8
+ attr_reader :contents
9
+
10
+ def initialize
11
+ @name = 'requestInspector.js'
12
+ @path = 'js'
13
+ end
14
+
15
+ def create
16
+ puts "called create of #{@filename}"
17
+ end
18
+
19
+ def contents
20
+ <<-"...".gsub!(/^ {2}/, '')
21
+ RequestInspector = function(instanceId) {
22
+ //some init logic here
23
+ };
24
+
25
+ //Method, which must be executed to start listening of network requests
26
+ RequestInspector.prototype.start = function() {
27
+ var self = this;
28
+ chrome.webRequest.onBeforeRequest.addListener(function (details) {
29
+ return RequestInspector.inspect(self, details);
30
+ }, {urls: ['<all_urls>']}, ['blocking']);
31
+ };
32
+
33
+ //Method, that receives every request made.
34
+ //It can cancel it or redirect. For cancel, it must return {cancel: true} object, for redirect {redirectUrl: url} object
35
+ RequestInspector.prototype.inspect = function(instance, details) {
36
+ console.log("inspected request object", details)
37
+ };
38
+
39
+ //this line is important for included scripts via require
40
+ exports.RequestInspector = RequestInspector;
41
+
42
+ ...
43
+ end
44
+
45
+
46
+
47
+ end
48
+
49
+
50
+ end
@@ -0,0 +1,3 @@
1
+ module Creng
2
+ VERSION = "0.4.2"
3
+ end
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: creng
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Andrew Stepikov
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-16 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rdf
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.3.10
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.3.10
30
+ description: Using this gem, you can create chrome extension skeleton with no troubles
31
+ email:
32
+ - stagedown@gmail.com
33
+ executables:
34
+ - creng
35
+ extensions: []
36
+ extra_rdoc_files: []
37
+ files:
38
+ - .gitignore
39
+ - Gemfile
40
+ - README.md
41
+ - Rakefile
42
+ - bin/creng
43
+ - creng.gemspec
44
+ - lib/creng.rb
45
+ - lib/creng/feature.rb
46
+ - lib/creng/file_generator.rb
47
+ - lib/creng/file_processor.rb
48
+ - lib/creng/file_tweaker.rb
49
+ - lib/creng/files/backgroundjs.rb
50
+ - lib/creng/files/contentjs.rb
51
+ - lib/creng/files/daemonjs.rb
52
+ - lib/creng/files/processjs.rb
53
+ - lib/creng/files/requestInspectorjs.rb
54
+ - lib/creng/vendor/images/extension-16x16.png
55
+ - lib/creng/vendor/images/extension-48x48.png
56
+ - lib/creng/vendor/images/extension-64x64.png
57
+ - lib/creng/version.rb
58
+ homepage: http://markeeper.ru
59
+ licenses: []
60
+ post_install_message: This gem allows you to easily create, manage and develop your
61
+ own chrome extension. For detailed information about usage type 'creng help'
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project: creng
79
+ rubygems_version: 1.8.24
80
+ signing_key:
81
+ specification_version: 3
82
+ summary: Create chrome extension with ease
83
+ test_files: []