Merge lp:~matsubara/juju-gui/tarmac-test into lp:~juju-gui/juju-gui/juju-gui-test
- tarmac-test
- Merge into juju-gui-test
Proposed by
Diogo Matsubara
Status: | Merged |
---|---|
Approved by: | Diogo Matsubara |
Approved revision: | 756 |
Merged at revision: | 756 |
Proposed branch: | lp:~matsubara/juju-gui/tarmac-test |
Merge into: | lp:~juju-gui/juju-gui/juju-gui-test |
Diff against target: |
14792 lines (+8357/-2851) (has conflicts) 132 files modified
.jshintignore (+1/-0) CHANGES.yaml (+37/-6) Makefile (+29/-11) README (+4/-0) app/app.js (+87/-27) app/assets/images/non-sprites/category-app-server.svg (+124/-0) app/assets/images/non-sprites/category-application.svg (+90/-0) app/assets/images/non-sprites/category-cache-proxy.svg (+119/-0) app/assets/images/non-sprites/category-database.svg (+115/-0) app/assets/images/non-sprites/category-file-server.svg (+74/-0) app/assets/images/non-sprites/category-misc.svg (+90/-0) app/assets/images/non-sprites/category_icons/category-app-server.svg (+124/-0) app/assets/images/non-sprites/category_icons/category-application.svg (+90/-0) app/assets/images/non-sprites/category_icons/category-cache-proxy.svg (+119/-0) app/assets/images/non-sprites/category_icons/category-database.svg (+115/-0) app/assets/images/non-sprites/category_icons/category-file-server.svg (+74/-0) app/assets/images/non-sprites/category_icons/category-misc.svg (+90/-0) app/assets/javascripts/Object.observe.poly.js (+246/-0) app/assets/javascripts/app-cookies-extension.js (+75/-0) app/assets/javascripts/ns-routing-app-extension.js (+72/-22) app/assets/javascripts/reconnecting-websocket.js (+10/-8) app/assets/stylesheets/bootstrap-responsive-2.0.4.css (+0/-815) app/assets/stylesheets/juju-bootstrap.css (+156/-0) app/config-debug.js (+4/-0) app/config-prod.js (+4/-0) app/index.html (+76/-50) app/models/browser.js (+26/-1) app/models/charm.js (+137/-17) app/models/handlers.js (+3/-3) app/models/models.js (+28/-2) app/modules-debug.js (+31/-2) app/store/charm.js (+25/-3) app/store/env/fakebackend.js (+51/-11) app/store/env/go.js (+53/-0) app/store/env/sandbox.js (+231/-1) app/subapps/browser/browser.js (+192/-33) app/subapps/browser/templates/browser_charm.handlebars (+26/-11) app/subapps/browser/templates/browser_qa.handlebars (+42/-23) app/subapps/browser/templates/editorial.handlebars (+6/-2) app/subapps/browser/templates/sidebar.handlebars (+3/-0) app/subapps/browser/views/charm.js (+135/-30) app/subapps/browser/views/charmresults.js (+2/-2) app/subapps/browser/views/editorial.js (+28/-1) app/subapps/browser/views/view.js (+1/-1) app/templates/browser-search.handlebars (+3/-0) app/templates/category-icons.partial (+55/-0) app/templates/charm-token.handlebars (+10/-1) app/templates/charm.handlebars (+1/-0) app/templates/notifications.handlebars (+2/-4) app/templates/overview.handlebars (+4/-0) app/templates/service-configuration.handlebars (+4/-0) app/templates/service-configuration.partial (+33/-0) app/templates/serviceOverview.handlebars (+13/-0) app/templates/sharing-widget.handlebars (+22/-0) app/templates/view-container.handlebars (+14/-0) app/views/charm-panel.js (+40/-597) app/views/databinding.js (+370/-0) app/views/environment.js (+34/-0) app/views/notifications.js (+1/-0) app/views/service.js (+125/-0) app/views/topology/importexport.js (+6/-1) app/views/topology/landscape.js (+6/-1) app/views/topology/panzoom.js (+34/-6) app/views/topology/relation.js (+6/-1) app/views/topology/service.js (+89/-6) app/views/topology/utils.js (+37/-2) app/views/topology/viewport.js (+6/-1) app/views/utils.js (+27/-16) app/views/view-container.js (+361/-0) app/websocket-logging.js (+123/-0) app/widgets/charm-search.js (+1/-1) app/widgets/charm-token.js (+13/-2) app/widgets/sharing-widget.js (+92/-0) bin/merge-files (+2/-1) bin/test-charm (+11/-9) docs/analytics.rst (+182/-0) docs/datasources.rst (+1/-1) docs/index.rst (+2/-0) docs/viewlet-data-binding.rst (+148/-0) lib/deploy_charm_for_testing.py (+0/-1) lib/templates.js (+1/-1) lib/views/browser/charm-full.less (+5/-5) lib/views/browser/charm-token.less (+2/-0) lib/views/browser/content-sidebar.less (+26/-1) lib/views/browser/editorial.less (+41/-0) lib/views/browser/main.less (+5/-3) lib/views/browser/minimized.less (+1/-0) lib/views/browser/mixins.less (+0/-26) lib/views/browser/sharing-widget.less (+23/-0) lib/views/cookies.less (+50/-0) lib/views/juju-inspector.less (+1/-1) lib/views/stylesheet.less (+185/-105) lib/websocketreplay.py (+8/-2) test/browser.py (+32/-10) test/data/related.json (+962/-0) test/index.html (+43/-16) test/test_app.js (+16/-12) test/test_application_notifications.js (+1/-0) test/test_browser_app.js (+129/-3) test/test_browser_charm_details.js (+177/-53) test/test_browser_editorial.js (+27/-8) test/test_browser_models.js (+9/-0) test/test_browser_search_view.js (+4/-3) test/test_charm_panel.js (+11/-449) test/test_charm_running.py (+102/-24) test/test_charm_store.js (+18/-8) test/test_charm_token.js (+35/-1) test/test_cookies_app_extension.js (+70/-0) test/test_databinding.js (+144/-0) test/test_deploy_charm_for_testing.py (+24/-14) test/test_endpoints.js (+4/-7) test/test_env_go.js (+2/-0) test/test_fakebackend.js (+69/-0) test/test_feature_flags.js (+20/-5) test/test_model.js (+102/-6) test/test_notifications.js (+16/-10) test/test_resizing_textarea.js (+4/-4) test/test_routing.js (+29/-3) test/test_sandbox.js (+241/-7) test/test_service_module.js (+12/-3) test/test_service_view.js (+181/-182) test/test_sharing_widget.js (+63/-0) test/test_startup.js.bottom (+1/-8) test/test_startup.js.top (+18/-0) test/test_topology.js (+18/-0) test/test_topology_utils.js (+17/-0) test/test_utils.js (+27/-0) test/test_view_container.js (+160/-0) test/test_websocket_logging.js (+109/-0) test/test_websocketreplay.py (+39/-0) test/utils.js (+28/-22) undocumented (+122/-116) Text conflict in README |
To merge this branch: | bzr merge lp:~matsubara/juju-gui/tarmac-test |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Diogo Matsubara | Approve | ||
Review via email: mp+171570@code.launchpad.net |
Commit message
test change
Description of the change
test change
To post a comment you must log in.
Revision history for this message
Diogo Matsubara (matsubara) : | # |
review:
Approve
Revision history for this message
Jujugui Lander (jujugui-lander) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file '.jshintignore' |
2 | --- .jshintignore 2013-05-14 17:31:39 +0000 |
3 | +++ .jshintignore 2013-06-26 14:26:26 +0000 |
4 | @@ -1,3 +1,4 @@ |
5 | app/assets/javascripts/prettify.js |
6 | app/assets/javascripts/FileSaver.js |
7 | app/assets/javascripts/unscaled-pack-layout.js |
8 | +app/assets/javascripts/Object.observe.poly.js |
9 | |
10 | === modified file 'CHANGES.yaml' |
11 | --- CHANGES.yaml 2013-05-23 22:12:32 +0000 |
12 | +++ CHANGES.yaml 2013-06-26 14:26:26 +0000 |
13 | @@ -22,29 +22,60 @@ |
14 | # [NUMBER].[NUMBER].[NUMBER] per http://semver.org/ . |
15 | |
16 | - unreleased: |
17 | +- 0.6.1: |
18 | + - > |
19 | + Fix critical jumping service bug (LP bug 1192596) and related drag |
20 | + problems on service creation. |
21 | + - Add feedback link. |
22 | + - Add prototype of data binding conflict resolution (feature-flagged). |
23 | + - > |
24 | + Add SetCharm to Go sandbox, in continuing preparation for supporting |
25 | + charm upgrades (not yet exposed to end-user). |
26 | + - Add incremental progress on charm sharing widget (feature-flagged). |
27 | + - Reduce test fragility and make other test improvements. |
28 | +- 0.6.0: |
29 | + - New charm browser for finding available charms. |
30 | + - Visual styling changes. |
31 | + - The beginnings of a Go backend sandbox. |
32 | + - Bug fixes and improved CI reliability. |
33 | + - Automatic view portal zoom and centering. |
34 | + - Support for Google Analytics. |
35 | + - Linting of yuidoc comments. |
36 | + - Linting of copyright headers. |
37 | + - Linting of project documentation files. |
38 | + - Utility for recording and playback of websocket traffic for debugging. |
39 | + - Caching of search results. |
40 | + - Improved development HTTP server behavior. |
41 | + - Improved project documentation. |
42 | - 0.5.0: |
43 | - Visual styling fixes. |
44 | - Many small bugfixes. |
45 | - Internal code reorganization and refactoring. |
46 | - - Configuration values can now be multi-line. The text entry widget |
47 | + - > |
48 | + Configuration values can now be multi-line. The text entry widget |
49 | automatically grows to accomodate multiple lines. |
50 | - Mousewheel zoom now works in firefox. |
51 | - The environment view now shows some help text when the canvas is empty. |
52 | - Changes to support faster deplyoment of the GUI charm (make npm-cache). |
53 | - - Experimental keyboard shortcuts. These will certainly change in the |
54 | + - > |
55 | + Experimental keyboard shortcuts. These will certainly change in the |
56 | future so don't train your fingers just yet. |
57 | - Experimental import/output functionality. Also sure to change. |
58 | - - No longer reports trivial errors caused by being in restricted |
59 | + - > |
60 | + No longer reports trivial errors caused by being in restricted |
61 | (read-only) mode. E.g., moving a service does not generate an error. |
62 | - Much nicer default layout of the services. |
63 | - - Removed HTML5 application cache as it was causing more problems than it |
64 | + - > |
65 | + Removed HTML5 application cache as it was causing more problems than it |
66 | was solving. |
67 | - Added licensing info to project (AGPL). |
68 | - - Fixed a memory leak in the code that reacts to changes coming from the |
69 | + - > |
70 | + Fixed a memory leak in the code that reacts to changes coming from the |
71 | Juju environment. |
72 | - 0.4.0: |
73 | - Support for Juju Core (Go Juju). |
74 | - - New "sandbox" mode for in-browser-memory fake juju (set "sandbox" to |
75 | + - > |
76 | + New "sandbox" mode for in-browser-memory fake juju (set "sandbox" to |
77 | "true" in config.js). |
78 | - Support for Firefox. |
79 | - Support for Landscape integration. |
80 | |
81 | === modified file 'Makefile' |
82 | --- Makefile 2013-05-29 19:06:28 +0000 |
83 | +++ Makefile 2013-06-26 14:26:26 +0000 |
84 | @@ -38,7 +38,7 @@ |
85 | -e '^app/assets/javascripts/gallery-.*\.js$$' \ |
86 | -e '^server.js$$') |
87 | THIRD_PARTY_JS=app/assets/javascripts/reconnecting-websocket.js |
88 | -LINT_IGNORE='app/assets/javascripts/prettify.js, app/assets/javascripts/FileSaver.js, app/assets/javascripts/spinner.js' |
89 | +LINT_IGNORE='app/assets/javascripts/prettify.js, app/assets/javascripts/FileSaver.js, app/assets/javascripts/spinner.js, app/assets/javascripts/Object.observe.poly.js' |
90 | NODE_TARGETS=node_modules/chai node_modules/cryptojs node_modules/d3 \ |
91 | node_modules/expect.js node_modules/express \ |
92 | node_modules/graceful-fs node_modules/grunt node_modules/jshint \ |
93 | @@ -143,7 +143,7 @@ |
94 | # As an optimization, we stash this value in the local PWD variable. |
95 | PWD=$(shell pwd) |
96 | |
97 | -all: build |
98 | +all: build virtualenv/bin/python |
99 | @echo "\nDebug and production environments built." |
100 | @echo "Run 'make help' to list the main available targets." |
101 | |
102 | @@ -172,7 +172,7 @@ |
103 | bin/generateTemplates |
104 | |
105 | yuidoc/index.html: node_modules/yuidocjs $(JSFILES) |
106 | - node_modules/.bin/yuidoc -o yuidoc -x assets app |
107 | + node_modules/.bin/yuidoc --lint -o yuidoc -x assets app |
108 | |
109 | main-doc: |
110 | make -C docs SPHINXOPTS=-W html |
111 | @@ -203,12 +203,12 @@ |
112 | |
113 | $(NON_SPRITE_IMAGES): |
114 | mkdir -p build-shared/juju-ui/assets/images |
115 | - cp app/assets/images/non-sprites/* build-shared/juju-ui/assets/images/ |
116 | + cp -r app/assets/images/non-sprites/* build-shared/juju-ui/assets/images/ |
117 | |
118 | install-npm-packages: $(NODE_TARGETS) |
119 | |
120 | $(NODE_TARGETS): package.json |
121 | - npm install |
122 | + npm install --cache-min=999999999 |
123 | # Keep all targets up to date, not just new/changed ones. |
124 | for dirname in $(NODE_TARGETS); do touch $$dirname ; done |
125 | @# Check to see if we made what we expected to make, and warn if we did |
126 | @@ -262,7 +262,8 @@ |
127 | undocumented: |
128 | bin/lint-yuidoc --generate-undocumented > undocumented |
129 | |
130 | -yuidoc-lint: $(JSFILES) |
131 | +lint-yuidoc: $(JSFILES) |
132 | + node_modules/.bin/yuidoc --lint -x assets app |
133 | bin/lint-yuidoc |
134 | |
135 | recess: node_modules/recess |
136 | @@ -272,10 +273,23 @@ |
137 | node_modules/recess/bin/recess lib/views/stylesheet.less \ |
138 | --config recess.json | grep -q Perfect |
139 | |
140 | -lint: test-prep jshint gjslint recess yuidoc-lint test-filtering |
141 | +lint: test-prep jshint gjslint recess lint-license-headers test-filtering \ |
142 | + lint-yuidoc |
143 | + |
144 | +lint-license-headers: |
145 | + @# Take the list of JS files in one long line and break them into |
146 | + @# multiple lines (this assumes there are no spaces in the paths). |
147 | + @# Remove non-JS files, remove third-party files, and remove files in |
148 | + @# the root of the project. Finally, search for copyright notices in |
149 | + @# the files and report files that do not have one. |
150 | + echo $(JSFILES) | sed 's/ /\n/g' \ |
151 | + | grep '\.js$$' | grep -v /assets/ | grep / \ |
152 | + | xargs -I {} sh -c "grep -L '^Copyright (C) 2[^ ]* Canonical Ltd.' {}" \ |
153 | + || (echo "The above files are missing copyright headers."; false) |
154 | |
155 | virtualenv/bin/python: |
156 | - virtualenv virtualenv |
157 | + virtualenv virtualenv --system-site-packages |
158 | + virtualenv/bin/easy_install archives/selenium-2.33.0.tar.gz |
159 | |
160 | virtualenv/bin/gjslint virtualenv/bin/fixjsstyle: virtualenv/bin/python |
161 | virtualenv/bin/easy_install archives/closure_linter-latest.tar.gz |
162 | @@ -317,6 +331,7 @@ |
163 | |
164 | LINK_DEBUG_FILES=$(call shared-link-files-list,debug) \ |
165 | build-debug/juju-ui/app.js \ |
166 | + build-debug/juju-ui/websocket-logging.js \ |
167 | build-debug/juju-ui/models \ |
168 | build-debug/juju-ui/store \ |
169 | build-debug/juju-ui/subapps \ |
170 | @@ -363,6 +378,7 @@ |
171 | $(LINK_DEBUG_FILES): |
172 | $(call link-files,debug) |
173 | ln -sf "$(PWD)/app/app.js" build-debug/juju-ui/ |
174 | + ln -sf "$(PWD)/app/websocket-logging.js" build-debug/juju-ui/ |
175 | ln -sf "$(PWD)/app/models" build-debug/juju-ui/ |
176 | ln -sf "$(PWD)/app/store" build-debug/juju-ui/ |
177 | ln -sf "$(PWD)/app/subapps" build-debug/juju-ui/ |
178 | @@ -456,6 +472,7 @@ |
179 | clean: |
180 | rm -rf build-shared build-debug build-prod |
181 | find app/assets/javascripts/ -type l | xargs rm -rf |
182 | + rm -f test/test_startup.js |
183 | |
184 | clean-deps: |
185 | rm -rf node_modules virtualenv |
186 | @@ -585,8 +602,9 @@ |
187 | # targets are alphabetically sorted, they like it that way :-) |
188 | .PHONY: beautify build build-files build-devel clean clean-all clean-deps \ |
189 | clean-docs code-doc debug devel docs dist gjslint help \ |
190 | - install-npm-packages jshint lint main-doc npm-cache npm-cache-file \ |
191 | - prep prod recess server spritegen test test-debug test-misc test-prep \ |
192 | - test-prod undocumented view-code-doc view-docs view-main-doc yuidoc-lint |
193 | + install-npm-packages jshint lint lint-yuidoc main-doc npm-cache \ |
194 | + npm-cache-file prep prod recess server spritegen test test-debug \ |
195 | + test-misc test-prep test-prod undocumented view-code-doc view-docs \ |
196 | + view-main-doc |
197 | |
198 | .DEFAULT_GOAL := all |
199 | |
200 | === modified file 'README' |
201 | --- README 2013-06-13 22:48:11 +0000 |
202 | +++ README 2013-06-26 14:26:26 +0000 |
203 | @@ -2,8 +2,12 @@ |
204 | alongside the whole project documentation. To do this, you need the |
205 | dependencies described in the "Documentation" section of the HACKING |
206 | file. |
207 | +<<<<<<< TREE |
208 | |
209 | foo |
210 | +======= |
211 | +one line change |
212 | +>>>>>>> MERGE-SOURCE |
213 | ====== |
214 | README |
215 | ====== |
216 | |
217 | === modified file 'app/app.js' |
218 | --- app/app.js 2013-05-28 12:43:25 +0000 |
219 | +++ app/app.js 2013-06-26 14:26:26 +0000 |
220 | @@ -47,12 +47,16 @@ |
221 | */ |
222 | var JujuGUI = Y.Base.create('juju-gui', Y.App, [ |
223 | Y.juju.SubAppRegistration, |
224 | - Y.juju.NSRouter], { |
225 | + Y.juju.NSRouter, |
226 | + Y.juju.Cookies], { |
227 | |
228 | /* |
229 | Extension properties |
230 | */ |
231 | - subApplications: [], |
232 | + subApplications: [{ |
233 | + type: Y.juju.subapps.Browser, |
234 | + config: {} |
235 | + }], |
236 | |
237 | defaultNamespace: 'charmstore', |
238 | /* |
239 | @@ -132,7 +136,7 @@ |
240 | |
241 | }, |
242 | |
243 | - /** |
244 | + /* |
245 | * Declarative keybindings on the window object. |
246 | * |
247 | * Prefix supported are: |
248 | @@ -197,14 +201,18 @@ |
249 | }, |
250 | help: 'Navigate to the Environment overview.' |
251 | }, |
252 | - '+': { |
253 | + 'S-+': { |
254 | fire: 'zoom_in', |
255 | help: 'Zoom In' |
256 | }, |
257 | - '-': { |
258 | + 'S--': { |
259 | fire: 'zoom_out', |
260 | help: 'Zoom Out' |
261 | }, |
262 | + 'S-0': { |
263 | + fire: 'panToCenter', |
264 | + help: 'Center the Environment overview' |
265 | + }, |
266 | 'esc': { |
267 | fire: 'clearState', |
268 | callback: function() { |
269 | @@ -226,7 +234,6 @@ |
270 | |
271 | 'S-d': { |
272 | callback: function(evt) { |
273 | - /* global saveAs: false */ |
274 | this.env.exportEnvironment(function(r) { |
275 | var exportData = JSON.stringify(r.result, undefined, 2); |
276 | var exportBlob = new Blob([exportData], |
277 | @@ -235,8 +242,16 @@ |
278 | }); |
279 | }, |
280 | help: 'Export the environment' |
281 | + }, |
282 | + |
283 | + 'C-S-d': { |
284 | + callback: function(evt) { |
285 | + Y.fire('saveWebsocketLog'); |
286 | + }, |
287 | + help: 'Save the websocket log to a file' |
288 | } |
289 | |
290 | + |
291 | }, |
292 | |
293 | /** |
294 | @@ -284,12 +299,22 @@ |
295 | }); |
296 | this._keybindings = Y.one(window).on('keydown', function(evt) { |
297 | //Normalize key-code |
298 | + var source = evt.target.getDOMNode(); |
299 | + // Target filtering, we want to listen on window |
300 | + // but not honor hotkeys when focused on |
301 | + // text oriented input fields |
302 | + if (['INPUT', 'TEXTAREA'].indexOf(source.tagName) !== -1) { |
303 | + return; |
304 | + } |
305 | var symbolic = []; |
306 | if (evt.ctrlKey) { symbolic.push('C');} |
307 | if (evt.altKey) { symbolic.push('A');} |
308 | if (evt.shiftKey) { symbolic.push('S');} |
309 | - symbolic.push(code_map[evt.keyCode] || |
310 | - String.fromCharCode(evt.keyCode).toLowerCase()); |
311 | + if (code_map[evt.keyCode]) { |
312 | + symbolic.push(code_map[evt.which]); |
313 | + } else { |
314 | + symbolic.push(String.fromCharCode(evt.which).toLowerCase()); |
315 | + } |
316 | var trigger = symbolic.join('-'); |
317 | var spec = this.keybindings[trigger]; |
318 | if (spec) { |
319 | @@ -335,15 +360,19 @@ |
320 | } |
321 | } |
322 | |
323 | - // XXX: #1185002 the charm browser subapp feature flag needs to be |
324 | - // removed |
325 | - if (window.flags.browser_enabled) { |
326 | - this.subApplications.push({ |
327 | - type: Y.juju.subapps.Browser, |
328 | - config: {} |
329 | - }); |
330 | + if (window.flags && window.flags.websocket_capture) { |
331 | + this.websocketLogging = new Y.juju.WebsocketLogging(); |
332 | } |
333 | |
334 | + /** |
335 | + Reference to the juju.Cookies instance. |
336 | + |
337 | + @property cookieHandler |
338 | + @type {juju.Cookies} |
339 | + @default null |
340 | + */ |
341 | + this.cookieHandler = null; |
342 | + |
343 | this.renderEnvironment = true; |
344 | // If this property has a value other than '/' then |
345 | // navigate to it after logging in. |
346 | @@ -418,7 +447,7 @@ |
347 | }; |
348 | var apiBackend = this.get('apiBackend'); |
349 | // The sandbox mode does not support the Go API (yet?). |
350 | - if (this.get('sandbox') && apiBackend === 'python') { |
351 | + if (this.get('sandbox')) { |
352 | var sandboxModule = Y.namespace('juju.environments.sandbox'); |
353 | var State = Y.namespace('juju.environments').FakeBackend; |
354 | var state = new State({charmStore: this.charm_store}); |
355 | @@ -427,8 +456,18 @@ |
356 | credentials[envOptions.user] = envOptions.password; |
357 | state.set('authorizedUsers', credentials); |
358 | } |
359 | - envOptions.conn = new sandboxModule.ClientConnection( |
360 | - {juju: new sandboxModule.PyJujuAPI({state: state})}); |
361 | + if (apiBackend === 'python') { |
362 | + envOptions.conn = new sandboxModule.ClientConnection( |
363 | + {juju: new sandboxModule.PyJujuAPI({state: state})}); |
364 | + } else if (apiBackend === 'go') { |
365 | + envOptions.conn = new sandboxModule.ClientConnection( |
366 | + {juju: new sandboxModule.GoJujuAPI({state: state})}); |
367 | + } else { |
368 | + // Clean ourselves up before giving up the ghost, for tests' sake. |
369 | + this.destroy(); |
370 | + throw 'unrecognized backend type: ' + apiBackend; |
371 | + } |
372 | + |
373 | } |
374 | this.env = juju.newEnvironment(envOptions, apiBackend); |
375 | } |
376 | @@ -518,10 +557,6 @@ |
377 | env: this.env, |
378 | app: this |
379 | }); |
380 | - this.charmPanel.setDefaultSeries(this.env.get('defaultSeries')); |
381 | - this.env.after('defaultSeriesChange', Y.bind(function(ev) { |
382 | - this.charmPanel.setDefaultSeries(ev.newVal); |
383 | - }, this)); |
384 | |
385 | // Halt the default navigation on the juju logo to allow us to show |
386 | // the real root view without namespaces |
387 | @@ -534,7 +569,10 @@ |
388 | }, this); |
389 | } |
390 | |
391 | - Y.one('#logout-trigger').on('click', this.logout, this); |
392 | + Y.one('#logout-trigger').on('click', function(e) { |
393 | + e.halt(); |
394 | + this.logout(); |
395 | + }, this); |
396 | |
397 | // Attach SubApplications. The subapps should share the same db. |
398 | cfg.db = this.db; |
399 | @@ -565,7 +603,7 @@ |
400 | catch (err) { |
401 | // Unable to create simulator, usually due to mocks or an |
402 | // unsupported environment |
403 | - console.log('Unable to create simulator: ', err); |
404 | + console.log('Unable to create simulator: '); |
405 | } |
406 | } |
407 | }, |
408 | @@ -908,7 +946,7 @@ |
409 | // If the Juju environment is not connected, exit without letting the |
410 | // route dispatch proceed. On env connection change, the app will |
411 | // re-dispatch and this route callback will be executed again. |
412 | - if (!this.env.get('connected')) { |
413 | + if (!this.env || !this.env.get('connected')) { |
414 | return; |
415 | } |
416 | var credentials = this.env.getCredentials(); |
417 | @@ -1181,6 +1219,24 @@ |
418 | finalPath = this.nsRouter.url({ gui: matches[idx].path }); |
419 | } |
420 | return finalPath; |
421 | + }, |
422 | + |
423 | + /** |
424 | + * Make sure the user agrees to cookie usage. |
425 | + * |
426 | + * @method authorizeCookieUse |
427 | + * @param {Object} req The request. |
428 | + * @param {Object} res The response. |
429 | + * @param {Object} next The next route handler. |
430 | + * |
431 | + */ |
432 | + authorizeCookieUse: function(req, res, next) { |
433 | + var analyticsEnabled = this.get('useAnalytics'); |
434 | + if (analyticsEnabled) { |
435 | + this.cookieHandler = this.cookieHandler || new Y.juju.Cookies(); |
436 | + this.cookieHandler.check(); |
437 | + } |
438 | + next(); |
439 | } |
440 | |
441 | }, { |
442 | @@ -1203,7 +1259,7 @@ |
443 | * `namespace`: (optional) when namespace is specified this route should |
444 | * only match when the URL fragment occurs in that namespace. The |
445 | * default namespace (as passed to this.nsRouter) is assumed if no |
446 | - * namespace attribute is specified. |
447 | + * namespace attribute is specified. |
448 | * |
449 | * `model`: `model.name` (required) |
450 | * |
451 | @@ -1224,6 +1280,7 @@ |
452 | { path: '*', callbacks: 'show_notifications_view'}, |
453 | { path: '*', callbacks: 'toggleStaticViews'}, |
454 | { path: '*', callbacks: 'show_environment'}, |
455 | + { path: '*', callbacks: 'authorizeCookieUse'}, |
456 | // Charms. |
457 | { path: '/charms/', |
458 | callbacks: 'show_charm_collection', |
459 | @@ -1271,7 +1328,7 @@ |
460 | |
461 | Y.namespace('juju').App = JujuGUI; |
462 | |
463 | -}, '0.5.2', { |
464 | +}, '0.5.3', { |
465 | requires: [ |
466 | 'juju-charm-models', |
467 | 'juju-charm-panel', |
468 | @@ -1291,6 +1348,7 @@ |
469 | 'juju-views', |
470 | 'juju-view-login', |
471 | 'juju-landscape', |
472 | + 'juju-websocket-logging', |
473 | 'io', |
474 | 'json-parse', |
475 | 'app-base', |
476 | @@ -1298,6 +1356,8 @@ |
477 | 'base', |
478 | 'node', |
479 | 'model', |
480 | + 'app-cookies-extension', |
481 | + 'cookie', |
482 | 'app-subapp-extension', |
483 | 'sub-app', |
484 | 'subapp-browser', |
485 | |
486 | === added file 'app/assets/images/charm-app-servers-160.png' |
487 | Binary files app/assets/images/charm-app-servers-160.png 1970-01-01 00:00:00 +0000 and app/assets/images/charm-app-servers-160.png 2013-06-26 14:26:26 +0000 differ |
488 | === added file 'app/assets/images/charm-app-servers-64.png' |
489 | Binary files app/assets/images/charm-app-servers-64.png 1970-01-01 00:00:00 +0000 and app/assets/images/charm-app-servers-64.png 2013-06-26 14:26:26 +0000 differ |
490 | === added file 'app/assets/images/charm-app-servers-96.png' |
491 | Binary files app/assets/images/charm-app-servers-96.png 1970-01-01 00:00:00 +0000 and app/assets/images/charm-app-servers-96.png 2013-06-26 14:26:26 +0000 differ |
492 | === added file 'app/assets/images/charm-applications-160.png' |
493 | Binary files app/assets/images/charm-applications-160.png 1970-01-01 00:00:00 +0000 and app/assets/images/charm-applications-160.png 2013-06-26 14:26:26 +0000 differ |
494 | === added file 'app/assets/images/charm-applications-64.png' |
495 | Binary files app/assets/images/charm-applications-64.png 1970-01-01 00:00:00 +0000 and app/assets/images/charm-applications-64.png 2013-06-26 14:26:26 +0000 differ |
496 | === added file 'app/assets/images/charm-applications-96.png' |
497 | Binary files app/assets/images/charm-applications-96.png 1970-01-01 00:00:00 +0000 and app/assets/images/charm-applications-96.png 2013-06-26 14:26:26 +0000 differ |
498 | === added file 'app/assets/images/charm-cache-proxy-160.png' |
499 | Binary files app/assets/images/charm-cache-proxy-160.png 1970-01-01 00:00:00 +0000 and app/assets/images/charm-cache-proxy-160.png 2013-06-26 14:26:26 +0000 differ |
500 | === added file 'app/assets/images/charm-cache-proxy-64.png' |
501 | Binary files app/assets/images/charm-cache-proxy-64.png 1970-01-01 00:00:00 +0000 and app/assets/images/charm-cache-proxy-64.png 2013-06-26 14:26:26 +0000 differ |
502 | === added file 'app/assets/images/charm-cache-proxy-96.png' |
503 | Binary files app/assets/images/charm-cache-proxy-96.png 1970-01-01 00:00:00 +0000 and app/assets/images/charm-cache-proxy-96.png 2013-06-26 14:26:26 +0000 differ |
504 | === added file 'app/assets/images/charm-databases-160.png' |
505 | Binary files app/assets/images/charm-databases-160.png 1970-01-01 00:00:00 +0000 and app/assets/images/charm-databases-160.png 2013-06-26 14:26:26 +0000 differ |
506 | === added file 'app/assets/images/charm-databases-64.png' |
507 | Binary files app/assets/images/charm-databases-64.png 1970-01-01 00:00:00 +0000 and app/assets/images/charm-databases-64.png 2013-06-26 14:26:26 +0000 differ |
508 | === added file 'app/assets/images/charm-databases-96.png' |
509 | Binary files app/assets/images/charm-databases-96.png 1970-01-01 00:00:00 +0000 and app/assets/images/charm-databases-96.png 2013-06-26 14:26:26 +0000 differ |
510 | === added file 'app/assets/images/charm-file-servers-160.png' |
511 | Binary files app/assets/images/charm-file-servers-160.png 1970-01-01 00:00:00 +0000 and app/assets/images/charm-file-servers-160.png 2013-06-26 14:26:26 +0000 differ |
512 | === added file 'app/assets/images/charm-file-servers-64.png' |
513 | Binary files app/assets/images/charm-file-servers-64.png 1970-01-01 00:00:00 +0000 and app/assets/images/charm-file-servers-64.png 2013-06-26 14:26:26 +0000 differ |
514 | === added file 'app/assets/images/charm-file-servers-96.png' |
515 | Binary files app/assets/images/charm-file-servers-96.png 1970-01-01 00:00:00 +0000 and app/assets/images/charm-file-servers-96.png 2013-06-26 14:26:26 +0000 differ |
516 | === added file 'app/assets/images/charm-misc-160.png' |
517 | Binary files app/assets/images/charm-misc-160.png 1970-01-01 00:00:00 +0000 and app/assets/images/charm-misc-160.png 2013-06-26 14:26:26 +0000 differ |
518 | === added file 'app/assets/images/charm-misc-64.png' |
519 | Binary files app/assets/images/charm-misc-64.png 1970-01-01 00:00:00 +0000 and app/assets/images/charm-misc-64.png 2013-06-26 14:26:26 +0000 differ |
520 | === added file 'app/assets/images/charm-misc-96.png' |
521 | Binary files app/assets/images/charm-misc-96.png 1970-01-01 00:00:00 +0000 and app/assets/images/charm-misc-96.png 2013-06-26 14:26:26 +0000 differ |
522 | === added file 'app/assets/images/email-click.png' |
523 | Binary files app/assets/images/email-click.png 1970-01-01 00:00:00 +0000 and app/assets/images/email-click.png 2013-06-26 14:26:26 +0000 differ |
524 | === added file 'app/assets/images/email-hover.png' |
525 | Binary files app/assets/images/email-hover.png 1970-01-01 00:00:00 +0000 and app/assets/images/email-hover.png 2013-06-26 14:26:26 +0000 differ |
526 | === added file 'app/assets/images/email-normal.png' |
527 | Binary files app/assets/images/email-normal.png 1970-01-01 00:00:00 +0000 and app/assets/images/email-normal.png 2013-06-26 14:26:26 +0000 differ |
528 | === added file 'app/assets/images/facebook-click.png' |
529 | Binary files app/assets/images/facebook-click.png 1970-01-01 00:00:00 +0000 and app/assets/images/facebook-click.png 2013-06-26 14:26:26 +0000 differ |
530 | === added file 'app/assets/images/facebook-hover.png' |
531 | Binary files app/assets/images/facebook-hover.png 1970-01-01 00:00:00 +0000 and app/assets/images/facebook-hover.png 2013-06-26 14:26:26 +0000 differ |
532 | === added file 'app/assets/images/facebook-normal.png' |
533 | Binary files app/assets/images/facebook-normal.png 1970-01-01 00:00:00 +0000 and app/assets/images/facebook-normal.png 2013-06-26 14:26:26 +0000 differ |
534 | === added file 'app/assets/images/google-click.png' |
535 | Binary files app/assets/images/google-click.png 1970-01-01 00:00:00 +0000 and app/assets/images/google-click.png 2013-06-26 14:26:26 +0000 differ |
536 | === added file 'app/assets/images/google-hover.png' |
537 | Binary files app/assets/images/google-hover.png 1970-01-01 00:00:00 +0000 and app/assets/images/google-hover.png 2013-06-26 14:26:26 +0000 differ |
538 | === added file 'app/assets/images/google-normal.png' |
539 | Binary files app/assets/images/google-normal.png 1970-01-01 00:00:00 +0000 and app/assets/images/google-normal.png 2013-06-26 14:26:26 +0000 differ |
540 | === added file 'app/assets/images/header_notification_centre.png' |
541 | Binary files app/assets/images/header_notification_centre.png 1970-01-01 00:00:00 +0000 and app/assets/images/header_notification_centre.png 2013-06-26 14:26:26 +0000 differ |
542 | === added file 'app/assets/images/header_notification_left.png' |
543 | Binary files app/assets/images/header_notification_left.png 1970-01-01 00:00:00 +0000 and app/assets/images/header_notification_left.png 2013-06-26 14:26:26 +0000 differ |
544 | === added file 'app/assets/images/header_notification_right.png' |
545 | Binary files app/assets/images/header_notification_right.png 1970-01-01 00:00:00 +0000 and app/assets/images/header_notification_right.png 2013-06-26 14:26:26 +0000 differ |
546 | === added file 'app/assets/images/juju_logo_dark.png' |
547 | Binary files app/assets/images/juju_logo_dark.png 1970-01-01 00:00:00 +0000 and app/assets/images/juju_logo_dark.png 2013-06-26 14:26:26 +0000 differ |
548 | === added file 'app/assets/images/non-sprites/category-app-server.svg' |
549 | --- app/assets/images/non-sprites/category-app-server.svg 1970-01-01 00:00:00 +0000 |
550 | +++ app/assets/images/non-sprites/category-app-server.svg 2013-06-26 14:26:26 +0000 |
551 | @@ -0,0 +1,124 @@ |
552 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
553 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> |
554 | + |
555 | +<svg |
556 | + xmlns:dc="http://purl.org/dc/elements/1.1/" |
557 | + xmlns:cc="http://creativecommons.org/ns#" |
558 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
559 | + xmlns:svg="http://www.w3.org/2000/svg" |
560 | + xmlns="http://www.w3.org/2000/svg" |
561 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
562 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
563 | + width="47.94035" |
564 | + height="47.94035" |
565 | + id="svg4400" |
566 | + version="1.1" |
567 | + inkscape:version="0.48.3.1 r9886" |
568 | + sodipodi:docname="category-app-server.svg"> |
569 | + <defs |
570 | + id="defs4402" /> |
571 | + <sodipodi:namedview |
572 | + id="base" |
573 | + pagecolor="#ffffff" |
574 | + bordercolor="#666666" |
575 | + borderopacity="1.0" |
576 | + inkscape:pageopacity="0.0" |
577 | + inkscape:pageshadow="2" |
578 | + inkscape:zoom="5.0931703" |
579 | + inkscape:cx="85.779492" |
580 | + inkscape:cy="6.1041666" |
581 | + inkscape:document-units="px" |
582 | + inkscape:current-layer="layer1" |
583 | + showgrid="true" |
584 | + fit-margin-top="0" |
585 | + fit-margin-left="0" |
586 | + fit-margin-right="0" |
587 | + fit-margin-bottom="0" |
588 | + inkscape:window-width="1920" |
589 | + inkscape:window-height="1029" |
590 | + inkscape:window-x="0" |
591 | + inkscape:window-y="24" |
592 | + inkscape:window-maximized="1"> |
593 | + <inkscape:grid |
594 | + type="xygrid" |
595 | + id="grid4469" |
596 | + empspacing="8" |
597 | + visible="true" |
598 | + enabled="true" |
599 | + snapvisiblegridlinesonly="true" /> |
600 | + </sodipodi:namedview> |
601 | + <metadata |
602 | + id="metadata4405"> |
603 | + <rdf:RDF> |
604 | + <cc:Work |
605 | + rdf:about=""> |
606 | + <dc:format>image/svg+xml</dc:format> |
607 | + <dc:type |
608 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
609 | + <dc:title></dc:title> |
610 | + </cc:Work> |
611 | + </rdf:RDF> |
612 | + </metadata> |
613 | + <g |
614 | + inkscape:label="Layer 1" |
615 | + inkscape:groupmode="layer" |
616 | + id="layer1" |
617 | + transform="translate(-630.31553,-996.96343)"> |
618 | + <g |
619 | + style="stroke:#505050;stroke-opacity:1;display:inline" |
620 | + id="g4781-3" |
621 | + transform="matrix(1.5005353,0,0,1.4833177,-852.22207,-34.476776)"> |
622 | + <path |
623 | + sodipodi:nodetypes="ccccc" |
624 | + inkscape:connector-curvature="0" |
625 | + id="path4783-4" |
626 | + d="m 996.33998,725.99069 7.65092,-3.80699 0,-8.70167 -7.65092,3.26312 z" |
627 | + style="color:#000000;fill:#505050;fill-opacity:1;stroke:#505050;stroke-width:2.01851225;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
628 | + <path |
629 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:1.982494;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
630 | + d="m 996.35027,726.0088 -7.35894,-3.81802 0,-8.72686 7.35894,3.27257 z" |
631 | + id="path4785-7" |
632 | + inkscape:connector-curvature="0" |
633 | + sodipodi:nodetypes="ccccc" /> |
634 | + <path |
635 | + inkscape:connector-curvature="0" |
636 | + id="path4787-1" |
637 | + d="m 996.50004,716.7407 7.50006,-3.26798 -7.50006,-3.81266 -7.50001,3.81266 z" |
638 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:2;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
639 | + <path |
640 | + style="color:#000000;fill:#505050;fill-opacity:1;stroke:#505050;stroke-width:1.98247516;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
641 | + d="m 1011.6499,726.00881 7.3589,-3.81802 0,-8.72688 -7.3589,3.27258 z" |
642 | + id="path4789-0" |
643 | + inkscape:connector-curvature="0" |
644 | + sodipodi:nodetypes="ccccc" /> |
645 | + <path |
646 | + sodipodi:nodetypes="ccccc" |
647 | + inkscape:connector-curvature="0" |
648 | + id="path4791-1" |
649 | + d="m 1011.6602,725.99068 -7.651,-3.80699 0,-8.70165 7.651,3.26312 z" |
650 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:2.01853108;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
651 | + <path |
652 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:2;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
653 | + d="m 1011.5,716.7407 7.5001,-3.26798 -7.5001,-3.81266 -7.5,3.81266 z" |
654 | + id="path4793-3" |
655 | + inkscape:connector-curvature="0" /> |
656 | + <path |
657 | + sodipodi:nodetypes="ccccc" |
658 | + inkscape:connector-curvature="0" |
659 | + id="path4795-6" |
660 | + d="m 1003.6526,713.34891 7.3564,-3.81813 0,-8.7271 -7.3564,3.27267 z" |
661 | + style="color:#000000;fill:#505050;fill-opacity:1;stroke:#505050;stroke-width:1.9821583;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
662 | + <path |
663 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:2.01884151;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
664 | + d="m 1003.6629,713.33046 -7.65353,-3.8069 0,-8.70143 7.65353,3.26304 z" |
665 | + id="path4797-0" |
666 | + inkscape:connector-curvature="0" |
667 | + sodipodi:nodetypes="ccccc" /> |
668 | + <path |
669 | + inkscape:connector-curvature="0" |
670 | + id="path4799-9" |
671 | + d="m 1003.5,704.08064 7.5001,-3.26799 L 1003.5,697 996,700.81265 z" |
672 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:2;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
673 | + </g> |
674 | + </g> |
675 | +</svg> |
676 | |
677 | === added file 'app/assets/images/non-sprites/category-application.svg' |
678 | --- app/assets/images/non-sprites/category-application.svg 1970-01-01 00:00:00 +0000 |
679 | +++ app/assets/images/non-sprites/category-application.svg 2013-06-26 14:26:26 +0000 |
680 | @@ -0,0 +1,90 @@ |
681 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
682 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> |
683 | + |
684 | +<svg |
685 | + xmlns:dc="http://purl.org/dc/elements/1.1/" |
686 | + xmlns:cc="http://creativecommons.org/ns#" |
687 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
688 | + xmlns:svg="http://www.w3.org/2000/svg" |
689 | + xmlns="http://www.w3.org/2000/svg" |
690 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
691 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
692 | + width="47.94035" |
693 | + height="47.94035" |
694 | + id="svg4400" |
695 | + version="1.1" |
696 | + inkscape:version="0.48.3.1 r9886" |
697 | + sodipodi:docname="category-application.svg"> |
698 | + <defs |
699 | + id="defs4402" /> |
700 | + <sodipodi:namedview |
701 | + id="base" |
702 | + pagecolor="#ffffff" |
703 | + bordercolor="#666666" |
704 | + borderopacity="1.0" |
705 | + inkscape:pageopacity="0.0" |
706 | + inkscape:pageshadow="2" |
707 | + inkscape:zoom="5.0931703" |
708 | + inkscape:cx="85.779492" |
709 | + inkscape:cy="6.1041666" |
710 | + inkscape:document-units="px" |
711 | + inkscape:current-layer="layer1" |
712 | + showgrid="true" |
713 | + fit-margin-top="0" |
714 | + fit-margin-left="0" |
715 | + fit-margin-right="0" |
716 | + fit-margin-bottom="0" |
717 | + inkscape:window-width="1920" |
718 | + inkscape:window-height="1029" |
719 | + inkscape:window-x="0" |
720 | + inkscape:window-y="24" |
721 | + inkscape:window-maximized="1"> |
722 | + <inkscape:grid |
723 | + type="xygrid" |
724 | + id="grid4469" |
725 | + empspacing="8" |
726 | + visible="true" |
727 | + enabled="true" |
728 | + snapvisiblegridlinesonly="true" /> |
729 | + </sodipodi:namedview> |
730 | + <metadata |
731 | + id="metadata4405"> |
732 | + <rdf:RDF> |
733 | + <cc:Work |
734 | + rdf:about=""> |
735 | + <dc:format>image/svg+xml</dc:format> |
736 | + <dc:type |
737 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
738 | + <dc:title></dc:title> |
739 | + </cc:Work> |
740 | + </rdf:RDF> |
741 | + </metadata> |
742 | + <g |
743 | + inkscape:label="Layer 1" |
744 | + inkscape:groupmode="layer" |
745 | + id="layer1" |
746 | + transform="translate(-630.31553,-996.96343)"> |
747 | + <g |
748 | + style="stroke:#505050;stroke-width:0.99999881;stroke-opacity:1;display:inline" |
749 | + id="g4746-5" |
750 | + transform="matrix(1.5000001,0,0,1.4999966,-852.18459,-227.09334)"> |
751 | + <path |
752 | + style="color:#000000;fill:#505050;fill-opacity:1;stroke:#505050;stroke-width:1.99999762;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
753 | + d="m 1004,847 14,-7 0,-16 -14,6 z" |
754 | + id="path4748-9" |
755 | + inkscape:connector-curvature="0" |
756 | + sodipodi:nodetypes="ccccc" /> |
757 | + <path |
758 | + sodipodi:nodetypes="ccccc" |
759 | + inkscape:connector-curvature="0" |
760 | + id="path4750-9" |
761 | + d="m 1004,847 -14,-7 0,-16 14,6 z" |
762 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:1.99999762;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
763 | + <path |
764 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:1.99999762;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
765 | + d="m 1004,830 14,-6 -14,-7 -14,7 z" |
766 | + id="path4752-1" |
767 | + inkscape:connector-curvature="0" /> |
768 | + </g> |
769 | + </g> |
770 | +</svg> |
771 | |
772 | === added file 'app/assets/images/non-sprites/category-cache-proxy.svg' |
773 | --- app/assets/images/non-sprites/category-cache-proxy.svg 1970-01-01 00:00:00 +0000 |
774 | +++ app/assets/images/non-sprites/category-cache-proxy.svg 2013-06-26 14:26:26 +0000 |
775 | @@ -0,0 +1,119 @@ |
776 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
777 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> |
778 | + |
779 | +<svg |
780 | + xmlns:dc="http://purl.org/dc/elements/1.1/" |
781 | + xmlns:cc="http://creativecommons.org/ns#" |
782 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
783 | + xmlns:svg="http://www.w3.org/2000/svg" |
784 | + xmlns="http://www.w3.org/2000/svg" |
785 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
786 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
787 | + width="47.94035" |
788 | + height="47.94035" |
789 | + id="svg4400" |
790 | + version="1.1" |
791 | + inkscape:version="0.48.3.1 r9886" |
792 | + sodipodi:docname="category-cache-proxy.svg"> |
793 | + <defs |
794 | + id="defs4402" /> |
795 | + <sodipodi:namedview |
796 | + id="base" |
797 | + pagecolor="#ffffff" |
798 | + bordercolor="#666666" |
799 | + borderopacity="1.0" |
800 | + inkscape:pageopacity="0.0" |
801 | + inkscape:pageshadow="2" |
802 | + inkscape:zoom="5.0931703" |
803 | + inkscape:cx="85.779492" |
804 | + inkscape:cy="6.1041666" |
805 | + inkscape:document-units="px" |
806 | + inkscape:current-layer="layer1" |
807 | + showgrid="true" |
808 | + fit-margin-top="0" |
809 | + fit-margin-left="0" |
810 | + fit-margin-right="0" |
811 | + fit-margin-bottom="0" |
812 | + inkscape:window-width="1920" |
813 | + inkscape:window-height="1029" |
814 | + inkscape:window-x="0" |
815 | + inkscape:window-y="24" |
816 | + inkscape:window-maximized="1"> |
817 | + <inkscape:grid |
818 | + type="xygrid" |
819 | + id="grid4469" |
820 | + empspacing="8" |
821 | + visible="true" |
822 | + enabled="true" |
823 | + snapvisiblegridlinesonly="true" /> |
824 | + </sodipodi:namedview> |
825 | + <metadata |
826 | + id="metadata4405"> |
827 | + <rdf:RDF> |
828 | + <cc:Work |
829 | + rdf:about=""> |
830 | + <dc:format>image/svg+xml</dc:format> |
831 | + <dc:type |
832 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
833 | + <dc:title></dc:title> |
834 | + </cc:Work> |
835 | + </rdf:RDF> |
836 | + </metadata> |
837 | + <g |
838 | + inkscape:label="Layer 1" |
839 | + inkscape:groupmode="layer" |
840 | + id="layer1" |
841 | + transform="translate(-630.31553,-996.96343)"> |
842 | + <path |
843 | + sodipodi:type="arc" |
844 | + style="color:#000000;fill:#505050;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
845 | + id="path3598" |
846 | + sodipodi:cx="1012" |
847 | + sodipodi:cy="420" |
848 | + sodipodi:rx="4" |
849 | + sodipodi:ry="4" |
850 | + d="m 1016,420 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z" |
851 | + transform="matrix(-1.625,0,0,1.625,2289.3155,329.90378)" /> |
852 | + <path |
853 | + transform="matrix(-1.625,0,0,1.625,2316.3155,329.90378)" |
854 | + d="m 1016,420 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z" |
855 | + sodipodi:ry="4" |
856 | + sodipodi:rx="4" |
857 | + sodipodi:cy="420" |
858 | + sodipodi:cx="1012" |
859 | + id="path4368" |
860 | + style="color:#000000;fill:#505050;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
861 | + sodipodi:type="arc" /> |
862 | + <path |
863 | + transform="matrix(-3.2499973,0,0,3.2499973,3933.8128,-352.59507)" |
864 | + d="m 1016,420 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z" |
865 | + sodipodi:ry="4" |
866 | + sodipodi:rx="4" |
867 | + sodipodi:cy="420" |
868 | + sodipodi:cx="1012" |
869 | + id="path4370" |
870 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:0.92307782;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
871 | + sodipodi:type="arc" /> |
872 | + <path |
873 | + sodipodi:type="arc" |
874 | + style="color:#000000;fill:#505050;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
875 | + id="path4372" |
876 | + sodipodi:cx="1012" |
877 | + sodipodi:cy="420" |
878 | + sodipodi:rx="4" |
879 | + sodipodi:ry="4" |
880 | + d="m 1016,420 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z" |
881 | + transform="matrix(-1.5,0,0,1.5,2178.3155,407.90378)" /> |
882 | + <path |
883 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.70000005;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
884 | + d="m 672.31551,1012.4038 -28.00004,0" |
885 | + id="path4374" |
886 | + inkscape:connector-curvature="0" /> |
887 | + <path |
888 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.70000005;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
889 | + d="m 661.31551,1039.9038 -17.00004,-28" |
890 | + id="path4376" |
891 | + inkscape:connector-curvature="0" |
892 | + sodipodi:nodetypes="cc" /> |
893 | + </g> |
894 | +</svg> |
895 | |
896 | === added file 'app/assets/images/non-sprites/category-database.svg' |
897 | --- app/assets/images/non-sprites/category-database.svg 1970-01-01 00:00:00 +0000 |
898 | +++ app/assets/images/non-sprites/category-database.svg 2013-06-26 14:26:26 +0000 |
899 | @@ -0,0 +1,115 @@ |
900 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
901 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> |
902 | + |
903 | +<svg |
904 | + xmlns:dc="http://purl.org/dc/elements/1.1/" |
905 | + xmlns:cc="http://creativecommons.org/ns#" |
906 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
907 | + xmlns:svg="http://www.w3.org/2000/svg" |
908 | + xmlns="http://www.w3.org/2000/svg" |
909 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
910 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
911 | + width="47.94035" |
912 | + height="47.94035" |
913 | + id="svg4400" |
914 | + version="1.1" |
915 | + inkscape:version="0.48.3.1 r9886" |
916 | + sodipodi:docname="category-database.svg"> |
917 | + <defs |
918 | + id="defs4402" /> |
919 | + <sodipodi:namedview |
920 | + id="base" |
921 | + pagecolor="#ffffff" |
922 | + bordercolor="#666666" |
923 | + borderopacity="1.0" |
924 | + inkscape:pageopacity="0.0" |
925 | + inkscape:pageshadow="2" |
926 | + inkscape:zoom="5.0931703" |
927 | + inkscape:cx="85.779492" |
928 | + inkscape:cy="6.1041666" |
929 | + inkscape:document-units="px" |
930 | + inkscape:current-layer="layer1" |
931 | + showgrid="true" |
932 | + fit-margin-top="0" |
933 | + fit-margin-left="0" |
934 | + fit-margin-right="0" |
935 | + fit-margin-bottom="0" |
936 | + inkscape:window-width="1920" |
937 | + inkscape:window-height="1029" |
938 | + inkscape:window-x="0" |
939 | + inkscape:window-y="24" |
940 | + inkscape:window-maximized="1"> |
941 | + <inkscape:grid |
942 | + type="xygrid" |
943 | + id="grid4469" |
944 | + empspacing="8" |
945 | + visible="true" |
946 | + enabled="true" |
947 | + snapvisiblegridlinesonly="true" /> |
948 | + </sodipodi:namedview> |
949 | + <metadata |
950 | + id="metadata4405"> |
951 | + <rdf:RDF> |
952 | + <cc:Work |
953 | + rdf:about=""> |
954 | + <dc:format>image/svg+xml</dc:format> |
955 | + <dc:type |
956 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
957 | + <dc:title></dc:title> |
958 | + </cc:Work> |
959 | + </rdf:RDF> |
960 | + </metadata> |
961 | + <g |
962 | + inkscape:label="Layer 1" |
963 | + inkscape:groupmode="layer" |
964 | + id="layer1" |
965 | + transform="translate(-630.31553,-996.96343)"> |
966 | + <g |
967 | + style="stroke:#505050;stroke-width:1;stroke-opacity:1;display:inline" |
968 | + id="g4760-2" |
969 | + transform="matrix(1.4999997,0,0,1.4999997,-851.68417,-316.59602)"> |
970 | + <path |
971 | + transform="matrix(0.78787872,0,0,1.3333333,212.57582,-288.66662)" |
972 | + d="m 1021,877 c 0,1.65685 -7.3873,3 -16.5,3 -9.1127,0 -16.5,-1.34315 -16.5,-3 0,-1.65685 7.3873,-3 16.5,-3 9.1127,0 16.5,1.34315 16.5,3 z" |
973 | + sodipodi:ry="3" |
974 | + sodipodi:rx="16.5" |
975 | + sodipodi:cy="877" |
976 | + sodipodi:cx="1004.5" |
977 | + id="path4762-0" |
978 | + style="color:#000000;fill:#505050;fill-opacity:1;stroke:#505050;stroke-width:1.95133114;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
979 | + sodipodi:type="arc" /> |
980 | + <path |
981 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:2.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
982 | + d="m 991,881 0,21.66665 0,0 c 0,2.20914 5.82029,4 13,4 7.1797,0 13,-1.79086 13,-4 L 1017,881" |
983 | + id="path4764-6" |
984 | + inkscape:connector-curvature="0" |
985 | + sodipodi:nodetypes="cccssc" /> |
986 | + <path |
987 | + sodipodi:type="arc" |
988 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:1.95133114;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
989 | + id="path4766-6" |
990 | + sodipodi:cx="1004.5" |
991 | + sodipodi:cy="877" |
992 | + sodipodi:rx="16.5" |
993 | + sodipodi:ry="3" |
994 | + d="m 1021,877 c 0,1.65685 -7.3873,3 -16.5,3 -7.46799,0 -14.00492,-0.91199 -15.93778,-2.22354" |
995 | + transform="matrix(0.78787872,0,0,1.3333333,212.57582,-281.33332)" |
996 | + sodipodi:start="0" |
997 | + sodipodi:end="2.8797933" |
998 | + sodipodi:open="true" /> |
999 | + <path |
1000 | + sodipodi:open="true" |
1001 | + sodipodi:end="2.8797933" |
1002 | + sodipodi:start="0" |
1003 | + transform="matrix(0.78787872,0,0,1.3333333,212.57582,-273.99995)" |
1004 | + d="m 1021,877 c 0,1.65685 -7.3873,3 -16.5,3 -7.46799,0 -14.00492,-0.91199 -15.93778,-2.22354" |
1005 | + sodipodi:ry="3" |
1006 | + sodipodi:rx="16.5" |
1007 | + sodipodi:cy="877" |
1008 | + sodipodi:cx="1004.5" |
1009 | + id="path4768-5" |
1010 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:1.95133114;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1011 | + sodipodi:type="arc" /> |
1012 | + </g> |
1013 | + </g> |
1014 | +</svg> |
1015 | |
1016 | === added file 'app/assets/images/non-sprites/category-file-server.svg' |
1017 | --- app/assets/images/non-sprites/category-file-server.svg 1970-01-01 00:00:00 +0000 |
1018 | +++ app/assets/images/non-sprites/category-file-server.svg 2013-06-26 14:26:26 +0000 |
1019 | @@ -0,0 +1,74 @@ |
1020 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
1021 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> |
1022 | + |
1023 | +<svg |
1024 | + xmlns:dc="http://purl.org/dc/elements/1.1/" |
1025 | + xmlns:cc="http://creativecommons.org/ns#" |
1026 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
1027 | + xmlns:svg="http://www.w3.org/2000/svg" |
1028 | + xmlns="http://www.w3.org/2000/svg" |
1029 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
1030 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
1031 | + width="47.94035" |
1032 | + height="47.94035" |
1033 | + id="svg4400" |
1034 | + version="1.1" |
1035 | + inkscape:version="0.48.3.1 r9886" |
1036 | + sodipodi:docname="category-file-server.svg"> |
1037 | + <defs |
1038 | + id="defs4402" /> |
1039 | + <sodipodi:namedview |
1040 | + id="base" |
1041 | + pagecolor="#ffffff" |
1042 | + bordercolor="#666666" |
1043 | + borderopacity="1.0" |
1044 | + inkscape:pageopacity="0.0" |
1045 | + inkscape:pageshadow="2" |
1046 | + inkscape:zoom="5.0931703" |
1047 | + inkscape:cx="85.779492" |
1048 | + inkscape:cy="6.1041666" |
1049 | + inkscape:document-units="px" |
1050 | + inkscape:current-layer="layer1" |
1051 | + showgrid="true" |
1052 | + fit-margin-top="0" |
1053 | + fit-margin-left="0" |
1054 | + fit-margin-right="0" |
1055 | + fit-margin-bottom="0" |
1056 | + inkscape:window-width="1920" |
1057 | + inkscape:window-height="1029" |
1058 | + inkscape:window-x="0" |
1059 | + inkscape:window-y="24" |
1060 | + inkscape:window-maximized="1"> |
1061 | + <inkscape:grid |
1062 | + type="xygrid" |
1063 | + id="grid4469" |
1064 | + empspacing="8" |
1065 | + visible="true" |
1066 | + enabled="true" |
1067 | + snapvisiblegridlinesonly="true" /> |
1068 | + </sodipodi:namedview> |
1069 | + <metadata |
1070 | + id="metadata4405"> |
1071 | + <rdf:RDF> |
1072 | + <cc:Work |
1073 | + rdf:about=""> |
1074 | + <dc:format>image/svg+xml</dc:format> |
1075 | + <dc:type |
1076 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
1077 | + <dc:title></dc:title> |
1078 | + </cc:Work> |
1079 | + </rdf:RDF> |
1080 | + </metadata> |
1081 | + <g |
1082 | + inkscape:label="Layer 1" |
1083 | + inkscape:groupmode="layer" |
1084 | + id="layer1" |
1085 | + transform="translate(-630.31553,-996.96343)"> |
1086 | + <path |
1087 | + inkscape:connector-curvature="0" |
1088 | + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#505050;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" |
1089 | + d="m 634.81553,996.90381 c -2.46705,0 -4.5,2.03295 -4.5,4.49999 l 0,3 0,1.5 0,25.5 c 0,2.4671 2.03295,4.5 4.5,4.5 l 9.5,0 0,-3 -9.5,0 c -0.85695,0 -1.5,-0.643 -1.5,-1.5 l 0,-25.5 0,-1.5 0,-3 c 0,-0.857 0.64305,-1.49999 1.5,-1.49999 l 12,0 c 0.8569,0 1.5,0.64299 1.5,1.49999 -0.002,0.047 -0.002,0.094 0,0.1406 l 0,1.3593 1.2657,0 0.2343,0 24,0 c 0.8569,0 1.5,0.6431 1.5,1.5 l 0,27 0,4.2188 c 1.7336,-0.6275 3,-2.2811 3,-4.2188 l 0,-27 c 0,-2.467 -2.0329,-4.49996 -4.5,-4.49996 l -23.1093,0 c -0.6631,-1.66422 -2.0029,-3 -3.8907,-3 l -12,0 z m 15.32985,16.99989 c -1.662,0 -3,1.338 -3,3 l 0,25.0001 c 0,1.662 1.338,3 3,3 l 19.17015,0 c 1.662,0 3,-1.338 3,-3 l 0,-25 c 0,-1.662 -1.338,-3 -3,-3 z m 2.41915,4.0001 c 0.016,-2e-4 0.031,-2e-4 0.047,0 0.047,0 0.094,0 0.141,0 0.047,0 0.094,0 0.141,0 0.047,0 0.094,0 0.141,0 l 13.775,0 c 0.7845,-0.011 1.506,0.7075 1.506,1.5 0,0.7925 -0.7215,1.5112 -1.506,1.5 l -13.775,0 c -0.7774,0.1238 -1.5963,-0.4779 -1.719,-1.2632 -0.1227,-0.7853 0.4727,-1.6126 1.2501,-1.7368 z m 0,6 c 0.016,-2e-4 0.031,-2e-4 0.047,0 0.047,0 0.094,0 0.141,0 0.047,0 0.094,0 0.141,0 0.047,0 0.094,0 0.141,0 l 13.775,0 c 0.7845,-0.011 1.506,0.7075 1.506,1.5 0,0.7926 -0.7215,1.5112 -1.506,1.5 l -13.775,0 c -0.7774,0.1238 -1.5963,-0.4779 -1.719,-1.2632 -0.1227,-0.7853 0.4727,-1.6126 1.2501,-1.7368 z m 0,6 c 0.016,-2e-4 0.031,-2e-4 0.047,0 0.047,0 0.094,0 0.141,0 0.047,0 0.094,0 0.141,0 0.047,0 0.094,0 0.141,0 l 7.775,0 c 0.7845,-0.011 1.506,0.7075 1.506,1.5 0,0.7926 -0.7215,1.5112 -1.506,1.5 l -7.775,0 c -0.7774,0.1238 -1.5963,-0.4779 -1.719,-1.2632 -0.1227,-0.7853 0.4727,-1.6126 1.2501,-1.7368 z" |
1090 | + id="rect4570-0" |
1091 | + sodipodi:nodetypes="csccssccssccssscccccssccssscsccsssssssssccccccsccsccccccccsccsccccccccsccscc" /> |
1092 | + </g> |
1093 | +</svg> |
1094 | |
1095 | === added file 'app/assets/images/non-sprites/category-misc.svg' |
1096 | --- app/assets/images/non-sprites/category-misc.svg 1970-01-01 00:00:00 +0000 |
1097 | +++ app/assets/images/non-sprites/category-misc.svg 2013-06-26 14:26:26 +0000 |
1098 | @@ -0,0 +1,90 @@ |
1099 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
1100 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> |
1101 | + |
1102 | +<svg |
1103 | + xmlns:dc="http://purl.org/dc/elements/1.1/" |
1104 | + xmlns:cc="http://creativecommons.org/ns#" |
1105 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
1106 | + xmlns:svg="http://www.w3.org/2000/svg" |
1107 | + xmlns="http://www.w3.org/2000/svg" |
1108 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
1109 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
1110 | + width="47.94035" |
1111 | + height="47.94035" |
1112 | + id="svg4400" |
1113 | + version="1.1" |
1114 | + inkscape:version="0.48.3.1 r9886" |
1115 | + sodipodi:docname="New document 3"> |
1116 | + <defs |
1117 | + id="defs4402" /> |
1118 | + <sodipodi:namedview |
1119 | + id="base" |
1120 | + pagecolor="#ffffff" |
1121 | + bordercolor="#666666" |
1122 | + borderopacity="1.0" |
1123 | + inkscape:pageopacity="0.0" |
1124 | + inkscape:pageshadow="2" |
1125 | + inkscape:zoom="6.3664629" |
1126 | + inkscape:cx="37.208976" |
1127 | + inkscape:cy="23.504348" |
1128 | + inkscape:document-units="px" |
1129 | + inkscape:current-layer="layer1" |
1130 | + showgrid="false" |
1131 | + fit-margin-top="0" |
1132 | + fit-margin-left="0" |
1133 | + fit-margin-right="0" |
1134 | + fit-margin-bottom="0" |
1135 | + inkscape:window-width="1920" |
1136 | + inkscape:window-height="1029" |
1137 | + inkscape:window-x="0" |
1138 | + inkscape:window-y="24" |
1139 | + inkscape:window-maximized="1" /> |
1140 | + <metadata |
1141 | + id="metadata4405"> |
1142 | + <rdf:RDF> |
1143 | + <cc:Work |
1144 | + rdf:about=""> |
1145 | + <dc:format>image/svg+xml</dc:format> |
1146 | + <dc:type |
1147 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
1148 | + <dc:title></dc:title> |
1149 | + </cc:Work> |
1150 | + </rdf:RDF> |
1151 | + </metadata> |
1152 | + <g |
1153 | + inkscape:label="Layer 1" |
1154 | + inkscape:groupmode="layer" |
1155 | + id="layer1" |
1156 | + transform="translate(-630.31553,-996.96343)"> |
1157 | + <g |
1158 | + style="stroke:#505050;stroke-opacity:1;display:inline" |
1159 | + id="g4736-4" |
1160 | + transform="matrix(1.4999966,0,0,1.4999966,-851.71092,-137.06381)"> |
1161 | + <path |
1162 | + transform="matrix(1.3636397,0,0,1.3636397,-365.09423,-280.72982)" |
1163 | + d="m 1015,772 c 0,6.07513 -4.9249,11 -11,11 -6.07513,0 -11,-4.92487 -11,-11 0,-6.07513 4.92487,-11 11,-11 6.0751,0 11,4.92487 11,11 z" |
1164 | + sodipodi:ry="11" |
1165 | + sodipodi:rx="11" |
1166 | + sodipodi:cy="772" |
1167 | + sodipodi:cx="1004" |
1168 | + id="path4738-2" |
1169 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:1.466663;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1170 | + sodipodi:type="arc" /> |
1171 | + <path |
1172 | + inkscape:connector-curvature="0" |
1173 | + id="path4740-2" |
1174 | + d="m 1003.6667,762.90178 0,18.19643" |
1175 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
1176 | + <path |
1177 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1178 | + d="m 1011.8793,767.45089 -15.75859,9.09821" |
1179 | + id="path4742-7" |
1180 | + inkscape:connector-curvature="0" /> |
1181 | + <path |
1182 | + inkscape:connector-curvature="0" |
1183 | + id="path4744-6" |
1184 | + d="m 1011.8793,776.54911 -15.75858,-9.09823" |
1185 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
1186 | + </g> |
1187 | + </g> |
1188 | +</svg> |
1189 | |
1190 | === added directory 'app/assets/images/non-sprites/category_icons' |
1191 | === added file 'app/assets/images/non-sprites/category_icons/category-app-server.svg' |
1192 | --- app/assets/images/non-sprites/category_icons/category-app-server.svg 1970-01-01 00:00:00 +0000 |
1193 | +++ app/assets/images/non-sprites/category_icons/category-app-server.svg 2013-06-26 14:26:26 +0000 |
1194 | @@ -0,0 +1,124 @@ |
1195 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
1196 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> |
1197 | + |
1198 | +<svg |
1199 | + xmlns:dc="http://purl.org/dc/elements/1.1/" |
1200 | + xmlns:cc="http://creativecommons.org/ns#" |
1201 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
1202 | + xmlns:svg="http://www.w3.org/2000/svg" |
1203 | + xmlns="http://www.w3.org/2000/svg" |
1204 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
1205 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
1206 | + width="47.94035" |
1207 | + height="47.94035" |
1208 | + id="svg4400" |
1209 | + version="1.1" |
1210 | + inkscape:version="0.48.3.1 r9886" |
1211 | + sodipodi:docname="category-app-server.svg"> |
1212 | + <defs |
1213 | + id="defs4402" /> |
1214 | + <sodipodi:namedview |
1215 | + id="base" |
1216 | + pagecolor="#ffffff" |
1217 | + bordercolor="#666666" |
1218 | + borderopacity="1.0" |
1219 | + inkscape:pageopacity="0.0" |
1220 | + inkscape:pageshadow="2" |
1221 | + inkscape:zoom="5.0931703" |
1222 | + inkscape:cx="85.779492" |
1223 | + inkscape:cy="6.1041666" |
1224 | + inkscape:document-units="px" |
1225 | + inkscape:current-layer="layer1" |
1226 | + showgrid="true" |
1227 | + fit-margin-top="0" |
1228 | + fit-margin-left="0" |
1229 | + fit-margin-right="0" |
1230 | + fit-margin-bottom="0" |
1231 | + inkscape:window-width="1920" |
1232 | + inkscape:window-height="1029" |
1233 | + inkscape:window-x="0" |
1234 | + inkscape:window-y="24" |
1235 | + inkscape:window-maximized="1"> |
1236 | + <inkscape:grid |
1237 | + type="xygrid" |
1238 | + id="grid4469" |
1239 | + empspacing="8" |
1240 | + visible="true" |
1241 | + enabled="true" |
1242 | + snapvisiblegridlinesonly="true" /> |
1243 | + </sodipodi:namedview> |
1244 | + <metadata |
1245 | + id="metadata4405"> |
1246 | + <rdf:RDF> |
1247 | + <cc:Work |
1248 | + rdf:about=""> |
1249 | + <dc:format>image/svg+xml</dc:format> |
1250 | + <dc:type |
1251 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
1252 | + <dc:title></dc:title> |
1253 | + </cc:Work> |
1254 | + </rdf:RDF> |
1255 | + </metadata> |
1256 | + <g |
1257 | + inkscape:label="Layer 1" |
1258 | + inkscape:groupmode="layer" |
1259 | + id="layer1" |
1260 | + transform="translate(-630.31553,-996.96343)"> |
1261 | + <g |
1262 | + style="stroke:#505050;stroke-opacity:1;display:inline" |
1263 | + id="g4781-3" |
1264 | + transform="matrix(1.5005353,0,0,1.4833177,-852.22207,-34.476776)"> |
1265 | + <path |
1266 | + sodipodi:nodetypes="ccccc" |
1267 | + inkscape:connector-curvature="0" |
1268 | + id="path4783-4" |
1269 | + d="m 996.33998,725.99069 7.65092,-3.80699 0,-8.70167 -7.65092,3.26312 z" |
1270 | + style="color:#000000;fill:#505050;fill-opacity:1;stroke:#505050;stroke-width:2.01851225;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
1271 | + <path |
1272 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:1.982494;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1273 | + d="m 996.35027,726.0088 -7.35894,-3.81802 0,-8.72686 7.35894,3.27257 z" |
1274 | + id="path4785-7" |
1275 | + inkscape:connector-curvature="0" |
1276 | + sodipodi:nodetypes="ccccc" /> |
1277 | + <path |
1278 | + inkscape:connector-curvature="0" |
1279 | + id="path4787-1" |
1280 | + d="m 996.50004,716.7407 7.50006,-3.26798 -7.50006,-3.81266 -7.50001,3.81266 z" |
1281 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:2;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
1282 | + <path |
1283 | + style="color:#000000;fill:#505050;fill-opacity:1;stroke:#505050;stroke-width:1.98247516;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1284 | + d="m 1011.6499,726.00881 7.3589,-3.81802 0,-8.72688 -7.3589,3.27258 z" |
1285 | + id="path4789-0" |
1286 | + inkscape:connector-curvature="0" |
1287 | + sodipodi:nodetypes="ccccc" /> |
1288 | + <path |
1289 | + sodipodi:nodetypes="ccccc" |
1290 | + inkscape:connector-curvature="0" |
1291 | + id="path4791-1" |
1292 | + d="m 1011.6602,725.99068 -7.651,-3.80699 0,-8.70165 7.651,3.26312 z" |
1293 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:2.01853108;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
1294 | + <path |
1295 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:2;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1296 | + d="m 1011.5,716.7407 7.5001,-3.26798 -7.5001,-3.81266 -7.5,3.81266 z" |
1297 | + id="path4793-3" |
1298 | + inkscape:connector-curvature="0" /> |
1299 | + <path |
1300 | + sodipodi:nodetypes="ccccc" |
1301 | + inkscape:connector-curvature="0" |
1302 | + id="path4795-6" |
1303 | + d="m 1003.6526,713.34891 7.3564,-3.81813 0,-8.7271 -7.3564,3.27267 z" |
1304 | + style="color:#000000;fill:#505050;fill-opacity:1;stroke:#505050;stroke-width:1.9821583;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
1305 | + <path |
1306 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:2.01884151;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1307 | + d="m 1003.6629,713.33046 -7.65353,-3.8069 0,-8.70143 7.65353,3.26304 z" |
1308 | + id="path4797-0" |
1309 | + inkscape:connector-curvature="0" |
1310 | + sodipodi:nodetypes="ccccc" /> |
1311 | + <path |
1312 | + inkscape:connector-curvature="0" |
1313 | + id="path4799-9" |
1314 | + d="m 1003.5,704.08064 7.5001,-3.26799 L 1003.5,697 996,700.81265 z" |
1315 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:2;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
1316 | + </g> |
1317 | + </g> |
1318 | +</svg> |
1319 | |
1320 | === added file 'app/assets/images/non-sprites/category_icons/category-application.svg' |
1321 | --- app/assets/images/non-sprites/category_icons/category-application.svg 1970-01-01 00:00:00 +0000 |
1322 | +++ app/assets/images/non-sprites/category_icons/category-application.svg 2013-06-26 14:26:26 +0000 |
1323 | @@ -0,0 +1,90 @@ |
1324 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
1325 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> |
1326 | + |
1327 | +<svg |
1328 | + xmlns:dc="http://purl.org/dc/elements/1.1/" |
1329 | + xmlns:cc="http://creativecommons.org/ns#" |
1330 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
1331 | + xmlns:svg="http://www.w3.org/2000/svg" |
1332 | + xmlns="http://www.w3.org/2000/svg" |
1333 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
1334 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
1335 | + width="47.94035" |
1336 | + height="47.94035" |
1337 | + id="svg4400" |
1338 | + version="1.1" |
1339 | + inkscape:version="0.48.3.1 r9886" |
1340 | + sodipodi:docname="category-application.svg"> |
1341 | + <defs |
1342 | + id="defs4402" /> |
1343 | + <sodipodi:namedview |
1344 | + id="base" |
1345 | + pagecolor="#ffffff" |
1346 | + bordercolor="#666666" |
1347 | + borderopacity="1.0" |
1348 | + inkscape:pageopacity="0.0" |
1349 | + inkscape:pageshadow="2" |
1350 | + inkscape:zoom="5.0931703" |
1351 | + inkscape:cx="85.779492" |
1352 | + inkscape:cy="6.1041666" |
1353 | + inkscape:document-units="px" |
1354 | + inkscape:current-layer="layer1" |
1355 | + showgrid="true" |
1356 | + fit-margin-top="0" |
1357 | + fit-margin-left="0" |
1358 | + fit-margin-right="0" |
1359 | + fit-margin-bottom="0" |
1360 | + inkscape:window-width="1920" |
1361 | + inkscape:window-height="1029" |
1362 | + inkscape:window-x="0" |
1363 | + inkscape:window-y="24" |
1364 | + inkscape:window-maximized="1"> |
1365 | + <inkscape:grid |
1366 | + type="xygrid" |
1367 | + id="grid4469" |
1368 | + empspacing="8" |
1369 | + visible="true" |
1370 | + enabled="true" |
1371 | + snapvisiblegridlinesonly="true" /> |
1372 | + </sodipodi:namedview> |
1373 | + <metadata |
1374 | + id="metadata4405"> |
1375 | + <rdf:RDF> |
1376 | + <cc:Work |
1377 | + rdf:about=""> |
1378 | + <dc:format>image/svg+xml</dc:format> |
1379 | + <dc:type |
1380 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
1381 | + <dc:title></dc:title> |
1382 | + </cc:Work> |
1383 | + </rdf:RDF> |
1384 | + </metadata> |
1385 | + <g |
1386 | + inkscape:label="Layer 1" |
1387 | + inkscape:groupmode="layer" |
1388 | + id="layer1" |
1389 | + transform="translate(-630.31553,-996.96343)"> |
1390 | + <g |
1391 | + style="stroke:#505050;stroke-width:0.99999881;stroke-opacity:1;display:inline" |
1392 | + id="g4746-5" |
1393 | + transform="matrix(1.5000001,0,0,1.4999966,-852.18459,-227.09334)"> |
1394 | + <path |
1395 | + style="color:#000000;fill:#505050;fill-opacity:1;stroke:#505050;stroke-width:1.99999762;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1396 | + d="m 1004,847 14,-7 0,-16 -14,6 z" |
1397 | + id="path4748-9" |
1398 | + inkscape:connector-curvature="0" |
1399 | + sodipodi:nodetypes="ccccc" /> |
1400 | + <path |
1401 | + sodipodi:nodetypes="ccccc" |
1402 | + inkscape:connector-curvature="0" |
1403 | + id="path4750-9" |
1404 | + d="m 1004,847 -14,-7 0,-16 14,6 z" |
1405 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:1.99999762;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
1406 | + <path |
1407 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:1.99999762;stroke-linejoin:round;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1408 | + d="m 1004,830 14,-6 -14,-7 -14,7 z" |
1409 | + id="path4752-1" |
1410 | + inkscape:connector-curvature="0" /> |
1411 | + </g> |
1412 | + </g> |
1413 | +</svg> |
1414 | |
1415 | === added file 'app/assets/images/non-sprites/category_icons/category-cache-proxy.svg' |
1416 | --- app/assets/images/non-sprites/category_icons/category-cache-proxy.svg 1970-01-01 00:00:00 +0000 |
1417 | +++ app/assets/images/non-sprites/category_icons/category-cache-proxy.svg 2013-06-26 14:26:26 +0000 |
1418 | @@ -0,0 +1,119 @@ |
1419 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
1420 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> |
1421 | + |
1422 | +<svg |
1423 | + xmlns:dc="http://purl.org/dc/elements/1.1/" |
1424 | + xmlns:cc="http://creativecommons.org/ns#" |
1425 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
1426 | + xmlns:svg="http://www.w3.org/2000/svg" |
1427 | + xmlns="http://www.w3.org/2000/svg" |
1428 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
1429 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
1430 | + width="47.94035" |
1431 | + height="47.94035" |
1432 | + id="svg4400" |
1433 | + version="1.1" |
1434 | + inkscape:version="0.48.3.1 r9886" |
1435 | + sodipodi:docname="category-cache-proxy.svg"> |
1436 | + <defs |
1437 | + id="defs4402" /> |
1438 | + <sodipodi:namedview |
1439 | + id="base" |
1440 | + pagecolor="#ffffff" |
1441 | + bordercolor="#666666" |
1442 | + borderopacity="1.0" |
1443 | + inkscape:pageopacity="0.0" |
1444 | + inkscape:pageshadow="2" |
1445 | + inkscape:zoom="5.0931703" |
1446 | + inkscape:cx="85.779492" |
1447 | + inkscape:cy="6.1041666" |
1448 | + inkscape:document-units="px" |
1449 | + inkscape:current-layer="layer1" |
1450 | + showgrid="true" |
1451 | + fit-margin-top="0" |
1452 | + fit-margin-left="0" |
1453 | + fit-margin-right="0" |
1454 | + fit-margin-bottom="0" |
1455 | + inkscape:window-width="1920" |
1456 | + inkscape:window-height="1029" |
1457 | + inkscape:window-x="0" |
1458 | + inkscape:window-y="24" |
1459 | + inkscape:window-maximized="1"> |
1460 | + <inkscape:grid |
1461 | + type="xygrid" |
1462 | + id="grid4469" |
1463 | + empspacing="8" |
1464 | + visible="true" |
1465 | + enabled="true" |
1466 | + snapvisiblegridlinesonly="true" /> |
1467 | + </sodipodi:namedview> |
1468 | + <metadata |
1469 | + id="metadata4405"> |
1470 | + <rdf:RDF> |
1471 | + <cc:Work |
1472 | + rdf:about=""> |
1473 | + <dc:format>image/svg+xml</dc:format> |
1474 | + <dc:type |
1475 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
1476 | + <dc:title></dc:title> |
1477 | + </cc:Work> |
1478 | + </rdf:RDF> |
1479 | + </metadata> |
1480 | + <g |
1481 | + inkscape:label="Layer 1" |
1482 | + inkscape:groupmode="layer" |
1483 | + id="layer1" |
1484 | + transform="translate(-630.31553,-996.96343)"> |
1485 | + <path |
1486 | + sodipodi:type="arc" |
1487 | + style="color:#000000;fill:#505050;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1488 | + id="path3598" |
1489 | + sodipodi:cx="1012" |
1490 | + sodipodi:cy="420" |
1491 | + sodipodi:rx="4" |
1492 | + sodipodi:ry="4" |
1493 | + d="m 1016,420 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z" |
1494 | + transform="matrix(-1.625,0,0,1.625,2289.3155,329.90378)" /> |
1495 | + <path |
1496 | + transform="matrix(-1.625,0,0,1.625,2316.3155,329.90378)" |
1497 | + d="m 1016,420 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z" |
1498 | + sodipodi:ry="4" |
1499 | + sodipodi:rx="4" |
1500 | + sodipodi:cy="420" |
1501 | + sodipodi:cx="1012" |
1502 | + id="path4368" |
1503 | + style="color:#000000;fill:#505050;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1504 | + sodipodi:type="arc" /> |
1505 | + <path |
1506 | + transform="matrix(-3.2499973,0,0,3.2499973,3933.8128,-352.59507)" |
1507 | + d="m 1016,420 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z" |
1508 | + sodipodi:ry="4" |
1509 | + sodipodi:rx="4" |
1510 | + sodipodi:cy="420" |
1511 | + sodipodi:cx="1012" |
1512 | + id="path4370" |
1513 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:0.92307782;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1514 | + sodipodi:type="arc" /> |
1515 | + <path |
1516 | + sodipodi:type="arc" |
1517 | + style="color:#000000;fill:#505050;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1518 | + id="path4372" |
1519 | + sodipodi:cx="1012" |
1520 | + sodipodi:cy="420" |
1521 | + sodipodi:rx="4" |
1522 | + sodipodi:ry="4" |
1523 | + d="m 1016,420 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z" |
1524 | + transform="matrix(-1.5,0,0,1.5,2178.3155,407.90378)" /> |
1525 | + <path |
1526 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.70000005;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1527 | + d="m 672.31551,1012.4038 -28.00004,0" |
1528 | + id="path4374" |
1529 | + inkscape:connector-curvature="0" /> |
1530 | + <path |
1531 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.70000005;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1532 | + d="m 661.31551,1039.9038 -17.00004,-28" |
1533 | + id="path4376" |
1534 | + inkscape:connector-curvature="0" |
1535 | + sodipodi:nodetypes="cc" /> |
1536 | + </g> |
1537 | +</svg> |
1538 | |
1539 | === added file 'app/assets/images/non-sprites/category_icons/category-database.svg' |
1540 | --- app/assets/images/non-sprites/category_icons/category-database.svg 1970-01-01 00:00:00 +0000 |
1541 | +++ app/assets/images/non-sprites/category_icons/category-database.svg 2013-06-26 14:26:26 +0000 |
1542 | @@ -0,0 +1,115 @@ |
1543 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
1544 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> |
1545 | + |
1546 | +<svg |
1547 | + xmlns:dc="http://purl.org/dc/elements/1.1/" |
1548 | + xmlns:cc="http://creativecommons.org/ns#" |
1549 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
1550 | + xmlns:svg="http://www.w3.org/2000/svg" |
1551 | + xmlns="http://www.w3.org/2000/svg" |
1552 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
1553 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
1554 | + width="47.94035" |
1555 | + height="47.94035" |
1556 | + id="svg4400" |
1557 | + version="1.1" |
1558 | + inkscape:version="0.48.3.1 r9886" |
1559 | + sodipodi:docname="category-database.svg"> |
1560 | + <defs |
1561 | + id="defs4402" /> |
1562 | + <sodipodi:namedview |
1563 | + id="base" |
1564 | + pagecolor="#ffffff" |
1565 | + bordercolor="#666666" |
1566 | + borderopacity="1.0" |
1567 | + inkscape:pageopacity="0.0" |
1568 | + inkscape:pageshadow="2" |
1569 | + inkscape:zoom="5.0931703" |
1570 | + inkscape:cx="85.779492" |
1571 | + inkscape:cy="6.1041666" |
1572 | + inkscape:document-units="px" |
1573 | + inkscape:current-layer="layer1" |
1574 | + showgrid="true" |
1575 | + fit-margin-top="0" |
1576 | + fit-margin-left="0" |
1577 | + fit-margin-right="0" |
1578 | + fit-margin-bottom="0" |
1579 | + inkscape:window-width="1920" |
1580 | + inkscape:window-height="1029" |
1581 | + inkscape:window-x="0" |
1582 | + inkscape:window-y="24" |
1583 | + inkscape:window-maximized="1"> |
1584 | + <inkscape:grid |
1585 | + type="xygrid" |
1586 | + id="grid4469" |
1587 | + empspacing="8" |
1588 | + visible="true" |
1589 | + enabled="true" |
1590 | + snapvisiblegridlinesonly="true" /> |
1591 | + </sodipodi:namedview> |
1592 | + <metadata |
1593 | + id="metadata4405"> |
1594 | + <rdf:RDF> |
1595 | + <cc:Work |
1596 | + rdf:about=""> |
1597 | + <dc:format>image/svg+xml</dc:format> |
1598 | + <dc:type |
1599 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
1600 | + <dc:title></dc:title> |
1601 | + </cc:Work> |
1602 | + </rdf:RDF> |
1603 | + </metadata> |
1604 | + <g |
1605 | + inkscape:label="Layer 1" |
1606 | + inkscape:groupmode="layer" |
1607 | + id="layer1" |
1608 | + transform="translate(-630.31553,-996.96343)"> |
1609 | + <g |
1610 | + style="stroke:#505050;stroke-width:1;stroke-opacity:1;display:inline" |
1611 | + id="g4760-2" |
1612 | + transform="matrix(1.4999997,0,0,1.4999997,-851.68417,-316.59602)"> |
1613 | + <path |
1614 | + transform="matrix(0.78787872,0,0,1.3333333,212.57582,-288.66662)" |
1615 | + d="m 1021,877 c 0,1.65685 -7.3873,3 -16.5,3 -9.1127,0 -16.5,-1.34315 -16.5,-3 0,-1.65685 7.3873,-3 16.5,-3 9.1127,0 16.5,1.34315 16.5,3 z" |
1616 | + sodipodi:ry="3" |
1617 | + sodipodi:rx="16.5" |
1618 | + sodipodi:cy="877" |
1619 | + sodipodi:cx="1004.5" |
1620 | + id="path4762-0" |
1621 | + style="color:#000000;fill:#505050;fill-opacity:1;stroke:#505050;stroke-width:1.95133114;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1622 | + sodipodi:type="arc" /> |
1623 | + <path |
1624 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:2.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1625 | + d="m 991,881 0,21.66665 0,0 c 0,2.20914 5.82029,4 13,4 7.1797,0 13,-1.79086 13,-4 L 1017,881" |
1626 | + id="path4764-6" |
1627 | + inkscape:connector-curvature="0" |
1628 | + sodipodi:nodetypes="cccssc" /> |
1629 | + <path |
1630 | + sodipodi:type="arc" |
1631 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:1.95133114;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1632 | + id="path4766-6" |
1633 | + sodipodi:cx="1004.5" |
1634 | + sodipodi:cy="877" |
1635 | + sodipodi:rx="16.5" |
1636 | + sodipodi:ry="3" |
1637 | + d="m 1021,877 c 0,1.65685 -7.3873,3 -16.5,3 -7.46799,0 -14.00492,-0.91199 -15.93778,-2.22354" |
1638 | + transform="matrix(0.78787872,0,0,1.3333333,212.57582,-281.33332)" |
1639 | + sodipodi:start="0" |
1640 | + sodipodi:end="2.8797933" |
1641 | + sodipodi:open="true" /> |
1642 | + <path |
1643 | + sodipodi:open="true" |
1644 | + sodipodi:end="2.8797933" |
1645 | + sodipodi:start="0" |
1646 | + transform="matrix(0.78787872,0,0,1.3333333,212.57582,-273.99995)" |
1647 | + d="m 1021,877 c 0,1.65685 -7.3873,3 -16.5,3 -7.46799,0 -14.00492,-0.91199 -15.93778,-2.22354" |
1648 | + sodipodi:ry="3" |
1649 | + sodipodi:rx="16.5" |
1650 | + sodipodi:cy="877" |
1651 | + sodipodi:cx="1004.5" |
1652 | + id="path4768-5" |
1653 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:1.95133114;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1654 | + sodipodi:type="arc" /> |
1655 | + </g> |
1656 | + </g> |
1657 | +</svg> |
1658 | |
1659 | === added file 'app/assets/images/non-sprites/category_icons/category-file-server.svg' |
1660 | --- app/assets/images/non-sprites/category_icons/category-file-server.svg 1970-01-01 00:00:00 +0000 |
1661 | +++ app/assets/images/non-sprites/category_icons/category-file-server.svg 2013-06-26 14:26:26 +0000 |
1662 | @@ -0,0 +1,74 @@ |
1663 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
1664 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> |
1665 | + |
1666 | +<svg |
1667 | + xmlns:dc="http://purl.org/dc/elements/1.1/" |
1668 | + xmlns:cc="http://creativecommons.org/ns#" |
1669 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
1670 | + xmlns:svg="http://www.w3.org/2000/svg" |
1671 | + xmlns="http://www.w3.org/2000/svg" |
1672 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
1673 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
1674 | + width="47.94035" |
1675 | + height="47.94035" |
1676 | + id="svg4400" |
1677 | + version="1.1" |
1678 | + inkscape:version="0.48.3.1 r9886" |
1679 | + sodipodi:docname="category-file-server.svg"> |
1680 | + <defs |
1681 | + id="defs4402" /> |
1682 | + <sodipodi:namedview |
1683 | + id="base" |
1684 | + pagecolor="#ffffff" |
1685 | + bordercolor="#666666" |
1686 | + borderopacity="1.0" |
1687 | + inkscape:pageopacity="0.0" |
1688 | + inkscape:pageshadow="2" |
1689 | + inkscape:zoom="5.0931703" |
1690 | + inkscape:cx="85.779492" |
1691 | + inkscape:cy="6.1041666" |
1692 | + inkscape:document-units="px" |
1693 | + inkscape:current-layer="layer1" |
1694 | + showgrid="true" |
1695 | + fit-margin-top="0" |
1696 | + fit-margin-left="0" |
1697 | + fit-margin-right="0" |
1698 | + fit-margin-bottom="0" |
1699 | + inkscape:window-width="1920" |
1700 | + inkscape:window-height="1029" |
1701 | + inkscape:window-x="0" |
1702 | + inkscape:window-y="24" |
1703 | + inkscape:window-maximized="1"> |
1704 | + <inkscape:grid |
1705 | + type="xygrid" |
1706 | + id="grid4469" |
1707 | + empspacing="8" |
1708 | + visible="true" |
1709 | + enabled="true" |
1710 | + snapvisiblegridlinesonly="true" /> |
1711 | + </sodipodi:namedview> |
1712 | + <metadata |
1713 | + id="metadata4405"> |
1714 | + <rdf:RDF> |
1715 | + <cc:Work |
1716 | + rdf:about=""> |
1717 | + <dc:format>image/svg+xml</dc:format> |
1718 | + <dc:type |
1719 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
1720 | + <dc:title></dc:title> |
1721 | + </cc:Work> |
1722 | + </rdf:RDF> |
1723 | + </metadata> |
1724 | + <g |
1725 | + inkscape:label="Layer 1" |
1726 | + inkscape:groupmode="layer" |
1727 | + id="layer1" |
1728 | + transform="translate(-630.31553,-996.96343)"> |
1729 | + <path |
1730 | + inkscape:connector-curvature="0" |
1731 | + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#505050;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" |
1732 | + d="m 634.81553,996.90381 c -2.46705,0 -4.5,2.03295 -4.5,4.49999 l 0,3 0,1.5 0,25.5 c 0,2.4671 2.03295,4.5 4.5,4.5 l 9.5,0 0,-3 -9.5,0 c -0.85695,0 -1.5,-0.643 -1.5,-1.5 l 0,-25.5 0,-1.5 0,-3 c 0,-0.857 0.64305,-1.49999 1.5,-1.49999 l 12,0 c 0.8569,0 1.5,0.64299 1.5,1.49999 -0.002,0.047 -0.002,0.094 0,0.1406 l 0,1.3593 1.2657,0 0.2343,0 24,0 c 0.8569,0 1.5,0.6431 1.5,1.5 l 0,27 0,4.2188 c 1.7336,-0.6275 3,-2.2811 3,-4.2188 l 0,-27 c 0,-2.467 -2.0329,-4.49996 -4.5,-4.49996 l -23.1093,0 c -0.6631,-1.66422 -2.0029,-3 -3.8907,-3 l -12,0 z m 15.32985,16.99989 c -1.662,0 -3,1.338 -3,3 l 0,25.0001 c 0,1.662 1.338,3 3,3 l 19.17015,0 c 1.662,0 3,-1.338 3,-3 l 0,-25 c 0,-1.662 -1.338,-3 -3,-3 z m 2.41915,4.0001 c 0.016,-2e-4 0.031,-2e-4 0.047,0 0.047,0 0.094,0 0.141,0 0.047,0 0.094,0 0.141,0 0.047,0 0.094,0 0.141,0 l 13.775,0 c 0.7845,-0.011 1.506,0.7075 1.506,1.5 0,0.7925 -0.7215,1.5112 -1.506,1.5 l -13.775,0 c -0.7774,0.1238 -1.5963,-0.4779 -1.719,-1.2632 -0.1227,-0.7853 0.4727,-1.6126 1.2501,-1.7368 z m 0,6 c 0.016,-2e-4 0.031,-2e-4 0.047,0 0.047,0 0.094,0 0.141,0 0.047,0 0.094,0 0.141,0 0.047,0 0.094,0 0.141,0 l 13.775,0 c 0.7845,-0.011 1.506,0.7075 1.506,1.5 0,0.7926 -0.7215,1.5112 -1.506,1.5 l -13.775,0 c -0.7774,0.1238 -1.5963,-0.4779 -1.719,-1.2632 -0.1227,-0.7853 0.4727,-1.6126 1.2501,-1.7368 z m 0,6 c 0.016,-2e-4 0.031,-2e-4 0.047,0 0.047,0 0.094,0 0.141,0 0.047,0 0.094,0 0.141,0 0.047,0 0.094,0 0.141,0 l 7.775,0 c 0.7845,-0.011 1.506,0.7075 1.506,1.5 0,0.7926 -0.7215,1.5112 -1.506,1.5 l -7.775,0 c -0.7774,0.1238 -1.5963,-0.4779 -1.719,-1.2632 -0.1227,-0.7853 0.4727,-1.6126 1.2501,-1.7368 z" |
1733 | + id="rect4570-0" |
1734 | + sodipodi:nodetypes="csccssccssccssscccccssccssscsccsssssssssccccccsccsccccccccsccsccccccccsccscc" /> |
1735 | + </g> |
1736 | +</svg> |
1737 | |
1738 | === added file 'app/assets/images/non-sprites/category_icons/category-misc.svg' |
1739 | --- app/assets/images/non-sprites/category_icons/category-misc.svg 1970-01-01 00:00:00 +0000 |
1740 | +++ app/assets/images/non-sprites/category_icons/category-misc.svg 2013-06-26 14:26:26 +0000 |
1741 | @@ -0,0 +1,90 @@ |
1742 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
1743 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> |
1744 | + |
1745 | +<svg |
1746 | + xmlns:dc="http://purl.org/dc/elements/1.1/" |
1747 | + xmlns:cc="http://creativecommons.org/ns#" |
1748 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
1749 | + xmlns:svg="http://www.w3.org/2000/svg" |
1750 | + xmlns="http://www.w3.org/2000/svg" |
1751 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
1752 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
1753 | + width="47.94035" |
1754 | + height="47.94035" |
1755 | + id="svg4400" |
1756 | + version="1.1" |
1757 | + inkscape:version="0.48.3.1 r9886" |
1758 | + sodipodi:docname="New document 3"> |
1759 | + <defs |
1760 | + id="defs4402" /> |
1761 | + <sodipodi:namedview |
1762 | + id="base" |
1763 | + pagecolor="#ffffff" |
1764 | + bordercolor="#666666" |
1765 | + borderopacity="1.0" |
1766 | + inkscape:pageopacity="0.0" |
1767 | + inkscape:pageshadow="2" |
1768 | + inkscape:zoom="6.3664629" |
1769 | + inkscape:cx="37.208976" |
1770 | + inkscape:cy="23.504348" |
1771 | + inkscape:document-units="px" |
1772 | + inkscape:current-layer="layer1" |
1773 | + showgrid="false" |
1774 | + fit-margin-top="0" |
1775 | + fit-margin-left="0" |
1776 | + fit-margin-right="0" |
1777 | + fit-margin-bottom="0" |
1778 | + inkscape:window-width="1920" |
1779 | + inkscape:window-height="1029" |
1780 | + inkscape:window-x="0" |
1781 | + inkscape:window-y="24" |
1782 | + inkscape:window-maximized="1" /> |
1783 | + <metadata |
1784 | + id="metadata4405"> |
1785 | + <rdf:RDF> |
1786 | + <cc:Work |
1787 | + rdf:about=""> |
1788 | + <dc:format>image/svg+xml</dc:format> |
1789 | + <dc:type |
1790 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
1791 | + <dc:title></dc:title> |
1792 | + </cc:Work> |
1793 | + </rdf:RDF> |
1794 | + </metadata> |
1795 | + <g |
1796 | + inkscape:label="Layer 1" |
1797 | + inkscape:groupmode="layer" |
1798 | + id="layer1" |
1799 | + transform="translate(-630.31553,-996.96343)"> |
1800 | + <g |
1801 | + style="stroke:#505050;stroke-opacity:1;display:inline" |
1802 | + id="g4736-4" |
1803 | + transform="matrix(1.4999966,0,0,1.4999966,-851.71092,-137.06381)"> |
1804 | + <path |
1805 | + transform="matrix(1.3636397,0,0,1.3636397,-365.09423,-280.72982)" |
1806 | + d="m 1015,772 c 0,6.07513 -4.9249,11 -11,11 -6.07513,0 -11,-4.92487 -11,-11 0,-6.07513 4.92487,-11 11,-11 6.0751,0 11,4.92487 11,11 z" |
1807 | + sodipodi:ry="11" |
1808 | + sodipodi:rx="11" |
1809 | + sodipodi:cy="772" |
1810 | + sodipodi:cx="1004" |
1811 | + id="path4738-2" |
1812 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:1.466663;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1813 | + sodipodi:type="arc" /> |
1814 | + <path |
1815 | + inkscape:connector-curvature="0" |
1816 | + id="path4740-2" |
1817 | + d="m 1003.6667,762.90178 0,18.19643" |
1818 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
1819 | + <path |
1820 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1821 | + d="m 1011.8793,767.45089 -15.75859,9.09821" |
1822 | + id="path4742-7" |
1823 | + inkscape:connector-curvature="0" /> |
1824 | + <path |
1825 | + inkscape:connector-curvature="0" |
1826 | + id="path4744-6" |
1827 | + d="m 1011.8793,776.54911 -15.75858,-9.09823" |
1828 | + style="color:#000000;fill:none;stroke:#505050;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
1829 | + </g> |
1830 | + </g> |
1831 | +</svg> |
1832 | |
1833 | === added file 'app/assets/images/twitter-click.png' |
1834 | Binary files app/assets/images/twitter-click.png 1970-01-01 00:00:00 +0000 and app/assets/images/twitter-click.png 2013-06-26 14:26:26 +0000 differ |
1835 | === added file 'app/assets/images/twitter-hover.png' |
1836 | Binary files app/assets/images/twitter-hover.png 1970-01-01 00:00:00 +0000 and app/assets/images/twitter-hover.png 2013-06-26 14:26:26 +0000 differ |
1837 | === added file 'app/assets/images/twitter-normal.png' |
1838 | Binary files app/assets/images/twitter-normal.png 1970-01-01 00:00:00 +0000 and app/assets/images/twitter-normal.png 2013-06-26 14:26:26 +0000 differ |
1839 | === added file 'app/assets/javascripts/Object.observe.poly.js' |
1840 | --- app/assets/javascripts/Object.observe.poly.js 1970-01-01 00:00:00 +0000 |
1841 | +++ app/assets/javascripts/Object.observe.poly.js 2013-06-26 14:26:26 +0000 |
1842 | @@ -0,0 +1,246 @@ |
1843 | +/* |
1844 | + Tested against Chromium build with Object.observe and acts EXACTLY the same, |
1845 | + though Chromium build is MUCH faster |
1846 | + |
1847 | + Trying to stay as close to the spec as possible, |
1848 | + this is a work in progress, feel free to comment/update |
1849 | + |
1850 | + Specification: |
1851 | + http://wiki.ecmascript.org/doku.php?id=harmony:observe |
1852 | + |
1853 | + Built using parts of: |
1854 | + https://github.com/tvcutsem/harmony-reflect/blob/master/examples/observer.js |
1855 | + |
1856 | + Limits so far; |
1857 | + Built using polling... Will update again with polling/getter&setters to make things better at some point |
1858 | +*/ |
1859 | +'use strict'; |
1860 | +if (!Object.observe) { |
1861 | + (function(extend, global) { |
1862 | + var isCallable = (function(toString) { |
1863 | + var s = toString.call(toString), |
1864 | + u = typeof u; |
1865 | + return typeof global.alert === 'object' ? |
1866 | + function(f) { |
1867 | + return s === toString.call(f) || (!!f && typeof f.toString == u && typeof f.valueOf == u && /^\s*\bfunction\b/.test('' + f)); |
1868 | + } : |
1869 | + function(f) { |
1870 | + return s === toString.call(f); |
1871 | + } |
1872 | +; |
1873 | + })(extend.prototype.toString); |
1874 | + var isNumeric = function(n) { |
1875 | + return !isNaN(parseFloat(n)) && isFinite(n); |
1876 | + }; |
1877 | + var sameValue = function(x, y) { |
1878 | + if (x === y) { |
1879 | + return x !== 0 || 1 / x === 1 / y; |
1880 | + } |
1881 | + return x !== x && y !== y; |
1882 | + }; |
1883 | + var isAccessorDescriptor = function(desc) { |
1884 | + if (typeof(desc) === 'undefined') { |
1885 | + return false; |
1886 | + } |
1887 | + return ('get' in desc || 'set' in desc); |
1888 | + }; |
1889 | + var isDataDescriptor = function(desc) { |
1890 | + if (typeof(desc) === 'undefined') { |
1891 | + return false; |
1892 | + } |
1893 | + return ('value' in desc || 'writable' in desc); |
1894 | + }; |
1895 | + |
1896 | + var validateArguments = function(O, callback) { |
1897 | + if (typeof(O) !== 'object') { |
1898 | + // Throw Error |
1899 | + throw new TypeError('Object.observeObject called on non-object'); |
1900 | + } |
1901 | + if (isCallable(callback) === false) { |
1902 | + // Throw Error |
1903 | + throw new TypeError('Object.observeObject: Expecting function'); |
1904 | + } |
1905 | + if (Object.isFrozen(callback) === true) { |
1906 | + // Throw Error |
1907 | + throw new TypeError('Object.observeObject: Expecting unfrozen function'); |
1908 | + } |
1909 | + }; |
1910 | + |
1911 | + var Observer = (function() { |
1912 | + var wraped = []; |
1913 | + var Observer = function(O, callback) { |
1914 | + validateArguments(O, callback); |
1915 | + Object.getNotifier(O).addListener(callback); |
1916 | + if (wraped.indexOf(O) === -1) { |
1917 | + wraped.push(O); |
1918 | + }else { |
1919 | + Object.getNotifier(O)._checkPropertyListing(); |
1920 | + } |
1921 | + }; |
1922 | + |
1923 | + Observer.prototype.deliverChangeRecords = function(O) { |
1924 | + Object.getNotifier(O).deliverChangeRecords(); |
1925 | + }; |
1926 | + |
1927 | + wraped.lastScanned = 0; |
1928 | + var f = (function(wrapped) { |
1929 | + return function() { |
1930 | + var i = 0, l = wrapped.length, startTime = new Date(), takingTooLong = false; |
1931 | + for (i = wrapped.lastScanned; (i < l) && (!takingTooLong); i++) { |
1932 | + Object.getNotifier(wrapped[i])._checkPropertyListing(); |
1933 | + takingTooLong = ((new Date()) - startTime) > 100; // make sure we don't take more than 100 milliseconds to scan all objects |
1934 | + } |
1935 | + wrapped.lastScanned = i < l ? i : 0; // reset wrapped so we can make sure that we pick things back up |
1936 | + setTimeout(f, 100); |
1937 | + }; |
1938 | + })(wraped); |
1939 | + setTimeout(f, 100); |
1940 | + |
1941 | + return Observer; |
1942 | + })(); |
1943 | + |
1944 | + var Notifier = function(watching) { |
1945 | + var _listeners = [], _updates = [], _updater = false, properties = [], values = []; |
1946 | + var self = this; |
1947 | + Object.defineProperty(self, '_watching', { |
1948 | + get: (function(watched) { |
1949 | + return function() { |
1950 | + return watched; |
1951 | + }; |
1952 | + })(watching) |
1953 | + }); |
1954 | + var wrapProperty = function(object, prop) { |
1955 | + var propType = typeof(object[prop]), descriptor = Object.getOwnPropertyDescriptor(object, prop); |
1956 | + if ((prop === 'getNotifier') || isAccessorDescriptor(descriptor) || (!descriptor.enumerable)) { |
1957 | + return false; |
1958 | + } |
1959 | + if ((object instanceof Array) && isNumeric(prop)) { |
1960 | + var idx = properties.length; |
1961 | + properties[idx] = prop; |
1962 | + values[idx] = object[prop]; |
1963 | + return true; |
1964 | + } |
1965 | + (function(idx, prop) { |
1966 | + properties[idx] = prop; |
1967 | + values[idx] = object[prop]; |
1968 | + Object.defineProperty(object, prop, { |
1969 | + get: function() { |
1970 | + return values[idx]; |
1971 | + }, |
1972 | + set: function(value) { |
1973 | + if (!sameValue(values[idx], value)) { |
1974 | + Object.getNotifier(object).queueUpdate(object, prop, 'updated', values[idx]); |
1975 | + values[idx] = value; |
1976 | + } |
1977 | + } |
1978 | + }); |
1979 | + })(properties.length, prop); |
1980 | + return true; |
1981 | + }; |
1982 | + self._checkPropertyListing = function(dontQueueUpdates) { |
1983 | + var object = self._watching, keys = Object.keys(object), i = 0, l = keys.length; |
1984 | + var newKeys = [], oldKeys = properties.slice(0), updates = []; |
1985 | + var prop, queueUpdates = !dontQueueUpdates, propType, value, idx; |
1986 | + |
1987 | + for (i = 0; i < l; i++) { |
1988 | + prop = keys[i]; |
1989 | + value = object[prop]; |
1990 | + propType = typeof(value); |
1991 | + if ((idx = properties.indexOf(prop)) === -1) { |
1992 | + if (wrapProperty(object, prop) && queueUpdates) { |
1993 | + self.queueUpdate(object, prop, 'new', null, object[prop]); |
1994 | + } |
1995 | + }else { |
1996 | + if ((object instanceof Array) && (isNumeric(prop))) { |
1997 | + if (values[idx] !== value) { |
1998 | + if (queueUpdates) { |
1999 | + self.queueUpdate(object, prop, 'updated', values[idx], value); |
2000 | + } |
2001 | + values[idx] = value; |
2002 | + } |
2003 | + } |
2004 | + oldKeys.splice(oldKeys.indexOf(prop), 1); |
2005 | + } |
2006 | + } |
2007 | + if (queueUpdates) { |
2008 | + l = oldKeys.length; |
2009 | + for (i = 0; i < l; i++) { |
2010 | + idx = properties.indexOf(oldKeys[i]); |
2011 | + self.queueUpdate(object, oldKeys[i], 'deleted', values[idx]); |
2012 | + properties.splice(idx, 1); |
2013 | + values.splice(idx, 1); |
2014 | + } |
2015 | + } |
2016 | + }; |
2017 | + self.addListener = function(callback) { |
2018 | + var idx = _listeners.indexOf(callback); |
2019 | + if (idx === -1) { |
2020 | + _listeners.push(callback); |
2021 | + } |
2022 | + }; |
2023 | + self.removeListener = function(callback) { |
2024 | + var idx = _listeners.indexOf(callback); |
2025 | + if (idx > -1) { |
2026 | + _listeners.splice(idx, 1); |
2027 | + } |
2028 | + }; |
2029 | + self.listeners = function() { |
2030 | + return _listeners; |
2031 | + }; |
2032 | + self.queueUpdate = function(what, prop, type, was) { |
2033 | + this.queueUpdates([{ |
2034 | + type: type, |
2035 | + object: what, |
2036 | + name: prop, |
2037 | + oldValue: was |
2038 | + }]); |
2039 | + }; |
2040 | + self.queueUpdates = function(updates) { |
2041 | + var self = this, i = 0, l = updates.length || 0, update; |
2042 | + for (i = 0; i < l; i++) { |
2043 | + update = updates[i]; |
2044 | + _updates.push(update); |
2045 | + } |
2046 | + if (_updater) { |
2047 | + clearTimeout(_updater); |
2048 | + } |
2049 | + _updater = setTimeout(function() { |
2050 | + _updater = false; |
2051 | + self.deliverChangeRecords(); |
2052 | + }, 100); |
2053 | + }; |
2054 | + self.deliverChangeRecords = function() { |
2055 | + var i = 0, l = _listeners.length, keepRunning = true; |
2056 | + for (i = 0; i < l && keepRunning; i++) { |
2057 | + if (typeof(_listeners[i]) === 'function') { |
2058 | + if (_listeners[i] === console.log) { |
2059 | + console.log(_updates); |
2060 | + }else { |
2061 | + keepRunning = !(_listeners[i](_updates)); |
2062 | + } |
2063 | + } |
2064 | + } |
2065 | + _updates = []; |
2066 | + }; |
2067 | + self._checkPropertyListing(true); |
2068 | + }; |
2069 | + |
2070 | + var _notifiers = [], _indexes = []; |
2071 | + extend.getNotifier = function(O) { |
2072 | + var idx = _indexes.indexOf(O), notifier = idx > -1 ? _notifiers[idx] : false; |
2073 | + if (!notifier) { |
2074 | + idx = _indexes.length; |
2075 | + _indexes[idx] = O; |
2076 | + notifier = _notifiers[idx] = new Notifier(O); |
2077 | + } |
2078 | + return notifier; |
2079 | + }; |
2080 | + extend.observe = function(O, callback) { |
2081 | + return new Observer(O, callback); |
2082 | + }; |
2083 | + extend.unobserve = function(O, callback) { |
2084 | + validateArguments(O, callback); |
2085 | + extend.getNotifier(O).removeListener(callback); |
2086 | + }; |
2087 | + })(Object, this); |
2088 | +} |
2089 | |
2090 | === added file 'app/assets/javascripts/app-cookies-extension.js' |
2091 | --- app/assets/javascripts/app-cookies-extension.js 1970-01-01 00:00:00 +0000 |
2092 | +++ app/assets/javascripts/app-cookies-extension.js 2013-06-26 14:26:26 +0000 |
2093 | @@ -0,0 +1,75 @@ |
2094 | +/* |
2095 | +This file is part of the Juju GUI, which lets users view and manage Juju |
2096 | +environments within a graphical interface (https://launchpad.net/juju-gui). |
2097 | +Copyright (C) 2013 Canonical Ltd. |
2098 | + |
2099 | +This program is free software: you can redistribute it and/or modify it under |
2100 | +the terms of the GNU Affero General Public License version 3, as published by |
2101 | +the Free Software Foundation. |
2102 | + |
2103 | +This program is distributed in the hope that it will be useful, but WITHOUT |
2104 | +ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
2105 | +SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero |
2106 | +General Public License for more details. |
2107 | + |
2108 | +You should have received a copy of the GNU Affero General Public License along |
2109 | +with this program. If not, see <http://www.gnu.org/licenses/>. |
2110 | +*/ |
2111 | + |
2112 | +'use strict'; |
2113 | + |
2114 | +YUI.add('app-cookies-extension', function(Y) { |
2115 | + |
2116 | + /** |
2117 | + A cookies warning handler, enabled when using analytics. |
2118 | + |
2119 | + @class Cookies |
2120 | + @extension App |
2121 | + @param {Object} test_node DOM node only passed in in tests. |
2122 | + */ |
2123 | + function Cookies(test_node) { |
2124 | + this.node = test_node || Y.one('.cookie-policy'); |
2125 | + } |
2126 | + |
2127 | + Cookies.prototype = { |
2128 | + |
2129 | + /** |
2130 | + Check that the user accepted cookie usage, and if not display a cookie |
2131 | + usage warning. |
2132 | + |
2133 | + @method check |
2134 | + @return {undefined} Side-effects only. |
2135 | + */ |
2136 | + check: function() { |
2137 | + var self = this; |
2138 | + if (Y.Cookie.get('_cookies_accepted') !== 'true') { |
2139 | + this.node.setStyle('display', 'block'); |
2140 | + Y.one('.link-cta').once('click', function(evt) { |
2141 | + evt.preventDefault(); |
2142 | + self.close(); |
2143 | + }); |
2144 | + } |
2145 | + }, |
2146 | + |
2147 | + /** |
2148 | + Close the cookie usage warning and set a cookie to denote user agreement. |
2149 | + |
2150 | + @method close |
2151 | + @return {undefined} Side-effects only. |
2152 | + */ |
2153 | + close: function() { |
2154 | + this.node.setStyle('display', 'none'); |
2155 | + Y.Cookie.set('_cookies_accepted', 'true', |
2156 | + {expires: new Date('January 12, 2025')}); |
2157 | + } |
2158 | + |
2159 | + }; |
2160 | + |
2161 | + Y.namespace('juju').Cookies = Cookies; |
2162 | + |
2163 | +}, '0.1.0', { |
2164 | + requires: [ |
2165 | + 'base', |
2166 | + 'cookie' |
2167 | + ] |
2168 | +}); |
2169 | |
2170 | === modified file 'app/assets/javascripts/ns-routing-app-extension.js' |
2171 | --- app/assets/javascripts/ns-routing-app-extension.js 2013-05-22 18:47:13 +0000 |
2172 | +++ app/assets/javascripts/ns-routing-app-extension.js 2013-06-26 14:26:26 +0000 |
2173 | @@ -61,9 +61,29 @@ |
2174 | return result; |
2175 | } |
2176 | |
2177 | - var Routes = { |
2178 | - pairs: function() {return pairs(this);} |
2179 | - }; |
2180 | + var Routes = (function() { |
2181 | + function Routes() { |
2182 | + return Object.create(this, { |
2183 | + defaultNamespacePresent: { |
2184 | + enumerable: false, |
2185 | + writable: true |
2186 | + }, |
2187 | + hash: { |
2188 | + enumerable: false, |
2189 | + writable: true |
2190 | + }, |
2191 | + search: { |
2192 | + enumerable: false, |
2193 | + writable: true |
2194 | + }, |
2195 | + pairs: { |
2196 | + enumable: false, |
2197 | + value: function() {return pairs(this);} |
2198 | + } |
2199 | + }); |
2200 | + } |
2201 | + return Routes; |
2202 | + })(); |
2203 | |
2204 | // Multi dimensional router (TARDIS). |
2205 | var _Router = { |
2206 | @@ -81,6 +101,24 @@ |
2207 | }, |
2208 | |
2209 | /** |
2210 | + Return the #hash portion of the URL if present. |
2211 | + |
2212 | + @method getHash |
2213 | + @param {String} url to parse hash from. |
2214 | + @return {String} hash || null. |
2215 | + */ |
2216 | + getHash: function(url) { |
2217 | + // This will return an array with three values the whole matched hash, |
2218 | + // the hash symbol, and then the hash without the hash. |
2219 | + // It is quoted to shush the linter about the . |
2220 | + var match = url.match('(#)(.[^?\/]*)?'); |
2221 | + if (!match) { |
2222 | + return undefined; |
2223 | + } |
2224 | + return match[2]; |
2225 | + }, |
2226 | + |
2227 | + /** |
2228 | * Split a URL into components, a subset of the |
2229 | * Location Object. |
2230 | * |
2231 | @@ -94,6 +132,7 @@ |
2232 | }; |
2233 | var origin = this._regexUrlOrigin.exec(url); |
2234 | result.search = this.getQS(url); |
2235 | + result.hash = this.getHash(url); |
2236 | |
2237 | if (origin) { |
2238 | // Take the match. |
2239 | @@ -105,8 +144,9 @@ |
2240 | } |
2241 | |
2242 | if (result.search) { |
2243 | - result.pathname = result.pathname.substr(0, |
2244 | - (result.pathname.length - result.search.length) - 1); |
2245 | + result.pathname = result.pathname.substr( |
2246 | + 0, |
2247 | + (result.pathname.length - result.search.length) - 1); |
2248 | } |
2249 | |
2250 | return result; |
2251 | @@ -127,20 +167,23 @@ |
2252 | **/ |
2253 | parse: function(url, combineFlags) { |
2254 | combineFlags = Y.mix(this.combineFlags || {}, combineFlags, true); |
2255 | - var result = Object.create(Routes, { |
2256 | - defaultNamespacePresent: { |
2257 | - enumerable: false, |
2258 | - writable: true |
2259 | - } |
2260 | - }); |
2261 | + var result = new Routes(); |
2262 | var parts = this.split(url); |
2263 | url = parts.pathname; |
2264 | + result.hash = parts.hash; |
2265 | + result.search = parts.search; |
2266 | |
2267 | + // If there was a hash we need to split it off url |
2268 | + if (result.hash) { |
2269 | + url = url.slice(0, url.indexOf('#')); |
2270 | + } |
2271 | parts = url.split(this._fragment); |
2272 | - // > '/foo/bar'.split(this._fragment) |
2273 | - // ["/foo/bar"] |
2274 | - // > :baz:/foo/bar'.split(this._fragment) |
2275 | - // ["", ":baz:", "/foo/bar"] |
2276 | + // Example output |
2277 | + // '/foo/bar'.split(this._fragment) |
2278 | + // ["/foo/bar"] |
2279 | + // |
2280 | + // ':baz:/foo/bar'.split(this._fragment) |
2281 | + // ["", ":baz:", "/foo/bar"] |
2282 | if (parts[0]) { |
2283 | // This is a URL fragment without a namespace. |
2284 | parts[0] = rtrim(parts[0], '/') + '/'; |
2285 | @@ -225,11 +268,20 @@ |
2286 | }); |
2287 | |
2288 | url = slash(url); |
2289 | + |
2290 | + if (components.hash) { |
2291 | + url += '#' + components.hash; |
2292 | + } |
2293 | + |
2294 | + if (components.search) { |
2295 | + url += '?' + components.search; |
2296 | + } |
2297 | return url; |
2298 | }, |
2299 | |
2300 | /** |
2301 | - * Smartly combine new namespaced url components with old. |
2302 | + * Smartly combine new namespaced url components with old. Hash and |
2303 | + * query string parameters from the incoming URL are preserved. |
2304 | * |
2305 | * @method combine |
2306 | * @param {Object} orig url. |
2307 | @@ -260,7 +312,7 @@ |
2308 | // original value). |
2309 | delete incoming[this.defaultNamespace]; |
2310 | } |
2311 | - var output = {}; |
2312 | + var output = new Routes(); |
2313 | Y.each(orig, function(v, k) { |
2314 | if (v && !Y.Lang.isArray(v)) { |
2315 | v = [v]; |
2316 | @@ -290,9 +342,11 @@ |
2317 | } |
2318 | }); |
2319 | }); |
2320 | + |
2321 | + output.hash = incoming.hash; |
2322 | + output.search = incoming.search; |
2323 | url = this.url(output, {excludeRootPaths: true}); |
2324 | return url; |
2325 | - |
2326 | } |
2327 | }; |
2328 | |
2329 | @@ -363,11 +417,7 @@ |
2330 | delete options.overrideAllNamespaces; |
2331 | } else { |
2332 | var loc = Y.getLocation(); |
2333 | - var qs = this.nsRouter.getQS(url); |
2334 | result = this.nsRouter.combine(loc.pathname, url); |
2335 | - if (qs) { |
2336 | - result += '?' + qs; |
2337 | - } |
2338 | } |
2339 | if (Y.App.prototype._navigate.call(this, result, options)) { |
2340 | return true; |
2341 | |
2342 | === modified file 'app/assets/javascripts/reconnecting-websocket.js' |
2343 | --- app/assets/javascripts/reconnecting-websocket.js 2012-07-24 18:18:43 +0000 |
2344 | +++ app/assets/javascripts/reconnecting-websocket.js 2013-06-26 14:26:26 +0000 |
2345 | @@ -38,7 +38,7 @@ |
2346 | * onopen // sometime later... |
2347 | * onmessage |
2348 | * onmessage |
2349 | - * etc... |
2350 | + * etc... |
2351 | * |
2352 | * It is API compatible with the standard WebSocket API. |
2353 | * |
2354 | @@ -46,7 +46,7 @@ |
2355 | */ |
2356 | |
2357 | YUI.add("reconnecting-websocket", function(Y) { |
2358 | - |
2359 | + |
2360 | function ReconnectingWebSocket(url, protocols) { |
2361 | |
2362 | // These can be altered by calling code. |
2363 | @@ -58,7 +58,7 @@ |
2364 | var ws; |
2365 | var forcedClose = false; |
2366 | var timedOut = false; |
2367 | - |
2368 | + |
2369 | this.url = url; |
2370 | this.protocols = protocols; |
2371 | this.readyState = WebSocket.CONNECTING; |
2372 | @@ -81,7 +81,7 @@ |
2373 | if (self.debug || ReconnectingWebSocket.debugAll) { |
2374 | console.debug('ReconnectingWebSocket', 'attempt-connect', url); |
2375 | } |
2376 | - |
2377 | + |
2378 | var localWs = ws; |
2379 | var timeout = setTimeout(function() { |
2380 | if (self.debug || ReconnectingWebSocket.debugAll) { |
2381 | @@ -91,7 +91,7 @@ |
2382 | localWs.close(); |
2383 | timedOut = false; |
2384 | }, self.timeoutInterval); |
2385 | - |
2386 | + |
2387 | ws.onopen = function(event) { |
2388 | clearTimeout(timeout); |
2389 | if (self.debug || ReconnectingWebSocket.debugAll) { |
2390 | @@ -101,7 +101,7 @@ |
2391 | reconnectAttempt = false; |
2392 | self.onopen(event); |
2393 | }; |
2394 | - |
2395 | + |
2396 | ws.onclose = function(event) { |
2397 | clearTimeout(timeout); |
2398 | ws = null; |
2399 | @@ -125,7 +125,8 @@ |
2400 | if (self.debug || ReconnectingWebSocket.debugAll) { |
2401 | console.debug('ReconnectingWebSocket', 'onmessage', url, event.data); |
2402 | } |
2403 | - self.onmessage(event); |
2404 | + Y.fire('websocketReceive', event.data); |
2405 | + self.onmessage(event); |
2406 | }; |
2407 | ws.onerror = function(event) { |
2408 | if (self.debug || ReconnectingWebSocket.debugAll) { |
2409 | @@ -141,6 +142,7 @@ |
2410 | if (self.debug || ReconnectingWebSocket.debugAll) { |
2411 | console.debug('ReconnectingWebSocket', 'send', url, data); |
2412 | } |
2413 | + Y.fire('websocketSend', data); |
2414 | return ws.send(data); |
2415 | } else { |
2416 | throw 'INVALID_STATE_ERR : Pausing to reconnect websocket'; |
2417 | @@ -174,4 +176,4 @@ |
2418 | |
2419 | }, "0.1.0", { |
2420 | requires: ["base"] |
2421 | -}); |
2422 | \ No newline at end of file |
2423 | +}); |
2424 | |
2425 | === removed file 'app/assets/stylesheets/bootstrap-responsive-2.0.4.css' |
2426 | --- app/assets/stylesheets/bootstrap-responsive-2.0.4.css 2012-07-18 21:14:50 +0000 |
2427 | +++ app/assets/stylesheets/bootstrap-responsive-2.0.4.css 1970-01-01 00:00:00 +0000 |
2428 | @@ -1,815 +0,0 @@ |
2429 | -/*! |
2430 | - * Bootstrap Responsive v2.0.4 |
2431 | - * |
2432 | - * Copyright 2012 Twitter, Inc |
2433 | - * Licensed under the Apache License v2.0 |
2434 | - * http://www.apache.org/licenses/LICENSE-2.0 |
2435 | - * |
2436 | - * Designed and built with all the love in the world @twitter by @mdo and @fat. |
2437 | - */ |
2438 | - |
2439 | -.clearfix { |
2440 | - *zoom: 1; |
2441 | -} |
2442 | - |
2443 | -.clearfix:before, |
2444 | -.clearfix:after { |
2445 | - display: table; |
2446 | - content: ""; |
2447 | -} |
2448 | - |
2449 | -.clearfix:after { |
2450 | - clear: both; |
2451 | -} |
2452 | - |
2453 | -.hide-text { |
2454 | - font: 0/0 a; |
2455 | - color: transparent; |
2456 | - text-shadow: none; |
2457 | - background-color: transparent; |
2458 | - border: 0; |
2459 | -} |
2460 | - |
2461 | -.input-block-level { |
2462 | - display: block; |
2463 | - width: 100%; |
2464 | - min-height: 28px; |
2465 | - -webkit-box-sizing: border-box; |
2466 | - -moz-box-sizing: border-box; |
2467 | - -ms-box-sizing: border-box; |
2468 | - box-sizing: border-box; |
2469 | -} |
2470 | - |
2471 | -.hidden { |
2472 | - display: none; |
2473 | - visibility: hidden; |
2474 | -} |
2475 | - |
2476 | -.visible-phone { |
2477 | - display: none !important; |
2478 | -} |
2479 | - |
2480 | -.visible-tablet { |
2481 | - display: none !important; |
2482 | -} |
2483 | - |
2484 | -.hidden-desktop { |
2485 | - display: none !important; |
2486 | -} |
2487 | - |
2488 | -@media (max-width: 767px) { |
2489 | - .visible-phone { |
2490 | - display: inherit !important; |
2491 | - } |
2492 | - .hidden-phone { |
2493 | - display: none !important; |
2494 | - } |
2495 | - .hidden-desktop { |
2496 | - display: inherit !important; |
2497 | - } |
2498 | - .visible-desktop { |
2499 | - display: none !important; |
2500 | - } |
2501 | -} |
2502 | - |
2503 | -@media (min-width: 768px) and (max-width: 979px) { |
2504 | - .visible-tablet { |
2505 | - display: inherit !important; |
2506 | - } |
2507 | - .hidden-tablet { |
2508 | - display: none !important; |
2509 | - } |
2510 | - .hidden-desktop { |
2511 | - display: inherit !important; |
2512 | - } |
2513 | - .visible-desktop { |
2514 | - display: none !important ; |
2515 | - } |
2516 | -} |
2517 | - |
2518 | -@media (max-width: 480px) { |
2519 | - .nav-collapse { |
2520 | - -webkit-transform: translate3d(0, 0, 0); |
2521 | - } |
2522 | - .page-header h1 small { |
2523 | - display: block; |
2524 | - line-height: 18px; |
2525 | - } |
2526 | - input[type="checkbox"], |
2527 | - input[type="radio"] { |
2528 | - border: 1px solid #ccc; |
2529 | - } |
2530 | - .form-horizontal .control-group > label { |
2531 | - float: none; |
2532 | - width: auto; |
2533 | - padding-top: 0; |
2534 | - text-align: left; |
2535 | - } |
2536 | - .form-horizontal .controls { |
2537 | - margin-left: 0; |
2538 | - } |
2539 | - .form-horizontal .control-list { |
2540 | - padding-top: 0; |
2541 | - } |
2542 | - .form-horizontal .form-actions { |
2543 | - padding-right: 10px; |
2544 | - padding-left: 10px; |
2545 | - } |
2546 | - .modal { |
2547 | - position: absolute; |
2548 | - top: 10px; |
2549 | - right: 10px; |
2550 | - left: 10px; |
2551 | - width: auto; |
2552 | - margin: 0; |
2553 | - } |
2554 | - .modal.fade.in { |
2555 | - top: auto; |
2556 | - } |
2557 | - .modal-header .close { |
2558 | - padding: 10px; |
2559 | - margin: -10px; |
2560 | - } |
2561 | - .carousel-caption { |
2562 | - position: static; |
2563 | - } |
2564 | -} |
2565 | - |
2566 | -@media (max-width: 767px) { |
2567 | - body { |
2568 | - padding-right: 20px; |
2569 | - padding-left: 20px; |
2570 | - } |
2571 | - .navbar-fixed-top, |
2572 | - .navbar-fixed-bottom { |
2573 | - margin-right: -20px; |
2574 | - margin-left: -20px; |
2575 | - } |
2576 | - .container-fluid { |
2577 | - padding: 0; |
2578 | - } |
2579 | - .dl-horizontal dt { |
2580 | - float: none; |
2581 | - width: auto; |
2582 | - clear: none; |
2583 | - text-align: left; |
2584 | - } |
2585 | - .dl-horizontal dd { |
2586 | - margin-left: 0; |
2587 | - } |
2588 | - .container { |
2589 | - width: auto; |
2590 | - } |
2591 | - .row-fluid { |
2592 | - width: 100%; |
2593 | - } |
2594 | - .row, |
2595 | - .thumbnails { |
2596 | - margin-left: 0; |
2597 | - } |
2598 | - [class*="span"], |
2599 | - .row-fluid [class*="span"] { |
2600 | - display: block; |
2601 | - float: none; |
2602 | - width: auto; |
2603 | - margin-left: 0; |
2604 | - } |
2605 | - .input-large, |
2606 | - .input-xlarge, |
2607 | - .input-xxlarge, |
2608 | - input[class*="span"], |
2609 | - select[class*="span"], |
2610 | - textarea[class*="span"], |
2611 | - .uneditable-input { |
2612 | - display: block; |
2613 | - width: 100%; |
2614 | - min-height: 28px; |
2615 | - -webkit-box-sizing: border-box; |
2616 | - -moz-box-sizing: border-box; |
2617 | - -ms-box-sizing: border-box; |
2618 | - box-sizing: border-box; |
2619 | - } |
2620 | - .input-prepend input, |
2621 | - .input-append input, |
2622 | - .input-prepend input[class*="span"], |
2623 | - .input-append input[class*="span"] { |
2624 | - display: inline-block; |
2625 | - width: auto; |
2626 | - } |
2627 | -} |
2628 | - |
2629 | -@media (min-width: 768px) and (max-width: 979px) { |
2630 | - .row { |
2631 | - margin-left: -20px; |
2632 | - *zoom: 1; |
2633 | - } |
2634 | - .row:before, |
2635 | - .row:after { |
2636 | - display: table; |
2637 | - content: ""; |
2638 | - } |
2639 | - .row:after { |
2640 | - clear: both; |
2641 | - } |
2642 | - [class*="span"] { |
2643 | - float: left; |
2644 | - margin-left: 20px; |
2645 | - } |
2646 | - .container, |
2647 | - .navbar-fixed-top .container, |
2648 | - .navbar-fixed-bottom .container { |
2649 | - width: 724px; |
2650 | - } |
2651 | - .span12 { |
2652 | - width: 724px; |
2653 | - } |
2654 | - .span11 { |
2655 | - width: 662px; |
2656 | - } |
2657 | - .span10 { |
2658 | - width: 600px; |
2659 | - } |
2660 | - .span9 { |
2661 | - width: 538px; |
2662 | - } |
2663 | - .span8 { |
2664 | - width: 476px; |
2665 | - } |
2666 | - .span7 { |
2667 | - width: 414px; |
2668 | - } |
2669 | - .span6 { |
2670 | - width: 352px; |
2671 | - } |
2672 | - .span5 { |
2673 | - width: 290px; |
2674 | - } |
2675 | - .span4 { |
2676 | - width: 228px; |
2677 | - } |
2678 | - .span3 { |
2679 | - width: 166px; |
2680 | - } |
2681 | - .span2 { |
2682 | - width: 104px; |
2683 | - } |
2684 | - .span1 { |
2685 | - width: 42px; |
2686 | - } |
2687 | - .offset12 { |
2688 | - margin-left: 764px; |
2689 | - } |
2690 | - .offset11 { |
2691 | - margin-left: 702px; |
2692 | - } |
2693 | - .offset10 { |
2694 | - margin-left: 640px; |
2695 | - } |
2696 | - .offset9 { |
2697 | - margin-left: 578px; |
2698 | - } |
2699 | - .offset8 { |
2700 | - margin-left: 516px; |
2701 | - } |
2702 | - .offset7 { |
2703 | - margin-left: 454px; |
2704 | - } |
2705 | - .offset6 { |
2706 | - margin-left: 392px; |
2707 | - } |
2708 | - .offset5 { |
2709 | - margin-left: 330px; |
2710 | - } |
2711 | - .offset4 { |
2712 | - margin-left: 268px; |
2713 | - } |
2714 | - .offset3 { |
2715 | - margin-left: 206px; |
2716 | - } |
2717 | - .offset2 { |
2718 | - margin-left: 144px; |
2719 | - } |
2720 | - .offset1 { |
2721 | - margin-left: 82px; |
2722 | - } |
2723 | - .row-fluid { |
2724 | - width: 100%; |
2725 | - *zoom: 1; |
2726 | - } |
2727 | - .row-fluid:before, |
2728 | - .row-fluid:after { |
2729 | - display: table; |
2730 | - content: ""; |
2731 | - } |
2732 | - .row-fluid:after { |
2733 | - clear: both; |
2734 | - } |
2735 | - .row-fluid [class*="span"] { |
2736 | - display: block; |
2737 | - float: left; |
2738 | - width: 100%; |
2739 | - min-height: 28px; |
2740 | - margin-left: 2.762430939%; |
2741 | - *margin-left: 2.709239449638298%; |
2742 | - -webkit-box-sizing: border-box; |
2743 | - -moz-box-sizing: border-box; |
2744 | - -ms-box-sizing: border-box; |
2745 | - box-sizing: border-box; |
2746 | - } |
2747 | - .row-fluid [class*="span"]:first-child { |
2748 | - margin-left: 0; |
2749 | - } |
2750 | - .row-fluid .span12 { |
2751 | - width: 99.999999993%; |
2752 | - *width: 99.9468085036383%; |
2753 | - } |
2754 | - .row-fluid .span11 { |
2755 | - width: 91.436464082%; |
2756 | - *width: 91.38327259263829%; |
2757 | - } |
2758 | - .row-fluid .span10 { |
2759 | - width: 82.87292817100001%; |
2760 | - *width: 82.8197366816383%; |
2761 | - } |
2762 | - .row-fluid .span9 { |
2763 | - width: 74.30939226%; |
2764 | - *width: 74.25620077063829%; |
2765 | - } |
2766 | - .row-fluid .span8 { |
2767 | - width: 65.74585634900001%; |
2768 | - *width: 65.6926648596383%; |
2769 | - } |
2770 | - .row-fluid .span7 { |
2771 | - width: 57.182320438000005%; |
2772 | - *width: 57.129128948638304%; |
2773 | - } |
2774 | - .row-fluid .span6 { |
2775 | - width: 48.618784527%; |
2776 | - *width: 48.5655930376383%; |
2777 | - } |
2778 | - .row-fluid .span5 { |
2779 | - width: 40.055248616%; |
2780 | - *width: 40.0020571266383%; |
2781 | - } |
2782 | - .row-fluid .span4 { |
2783 | - width: 31.491712705%; |
2784 | - *width: 31.4385212156383%; |
2785 | - } |
2786 | - .row-fluid .span3 { |
2787 | - width: 22.928176794%; |
2788 | - *width: 22.874985304638297%; |
2789 | - } |
2790 | - .row-fluid .span2 { |
2791 | - width: 14.364640883%; |
2792 | - *width: 14.311449393638298%; |
2793 | - } |
2794 | - .row-fluid .span1 { |
2795 | - width: 5.801104972%; |
2796 | - *width: 5.747913482638298%; |
2797 | - } |
2798 | - input, |
2799 | - textarea, |
2800 | - .uneditable-input { |
2801 | - margin-left: 0; |
2802 | - } |
2803 | - input.span12, |
2804 | - textarea.span12, |
2805 | - .uneditable-input.span12 { |
2806 | - width: 714px; |
2807 | - } |
2808 | - input.span11, |
2809 | - textarea.span11, |
2810 | - .uneditable-input.span11 { |
2811 | - width: 652px; |
2812 | - } |
2813 | - input.span10, |
2814 | - textarea.span10, |
2815 | - .uneditable-input.span10 { |
2816 | - width: 590px; |
2817 | - } |
2818 | - input.span9, |
2819 | - textarea.span9, |
2820 | - .uneditable-input.span9 { |
2821 | - width: 528px; |
2822 | - } |
2823 | - input.span8, |
2824 | - textarea.span8, |
2825 | - .uneditable-input.span8 { |
2826 | - width: 466px; |
2827 | - } |
2828 | - input.span7, |
2829 | - textarea.span7, |
2830 | - .uneditable-input.span7 { |
2831 | - width: 404px; |
2832 | - } |
2833 | - input.span6, |
2834 | - textarea.span6, |
2835 | - .uneditable-input.span6 { |
2836 | - width: 342px; |
2837 | - } |
2838 | - input.span5, |
2839 | - textarea.span5, |
2840 | - .uneditable-input.span5 { |
2841 | - width: 280px; |
2842 | - } |
2843 | - input.span4, |
2844 | - textarea.span4, |
2845 | - .uneditable-input.span4 { |
2846 | - width: 218px; |
2847 | - } |
2848 | - input.span3, |
2849 | - textarea.span3, |
2850 | - .uneditable-input.span3 { |
2851 | - width: 156px; |
2852 | - } |
2853 | - input.span2, |
2854 | - textarea.span2, |
2855 | - .uneditable-input.span2 { |
2856 | - width: 94px; |
2857 | - } |
2858 | - input.span1, |
2859 | - textarea.span1, |
2860 | - .uneditable-input.span1 { |
2861 | - width: 32px; |
2862 | - } |
2863 | -} |
2864 | - |
2865 | -@media (min-width: 1200px) { |
2866 | - .row { |
2867 | - margin-left: -30px; |
2868 | - *zoom: 1; |
2869 | - } |
2870 | - .row:before, |
2871 | - .row:after { |
2872 | - display: table; |
2873 | - content: ""; |
2874 | - } |
2875 | - .row:after { |
2876 | - clear: both; |
2877 | - } |
2878 | - [class*="span"] { |
2879 | - float: left; |
2880 | - margin-left: 30px; |
2881 | - } |
2882 | - .container, |
2883 | - .navbar-fixed-top .container, |
2884 | - .navbar-fixed-bottom .container { |
2885 | - width: 1170px; |
2886 | - } |
2887 | - .span12 { |
2888 | - width: 1170px; |
2889 | - } |
2890 | - .span11 { |
2891 | - width: 1070px; |
2892 | - } |
2893 | - .span10 { |
2894 | - width: 970px; |
2895 | - } |
2896 | - .span9 { |
2897 | - width: 870px; |
2898 | - } |
2899 | - .span8 { |
2900 | - width: 770px; |
2901 | - } |
2902 | - .span7 { |
2903 | - width: 670px; |
2904 | - } |
2905 | - .span6 { |
2906 | - width: 570px; |
2907 | - } |
2908 | - .span5 { |
2909 | - width: 470px; |
2910 | - } |
2911 | - .span4 { |
2912 | - width: 370px; |
2913 | - } |
2914 | - .span3 { |
2915 | - width: 270px; |
2916 | - } |
2917 | - .span2 { |
2918 | - width: 170px; |
2919 | - } |
2920 | - .span1 { |
2921 | - width: 70px; |
2922 | - } |
2923 | - .offset12 { |
2924 | - margin-left: 1230px; |
2925 | - } |
2926 | - .offset11 { |
2927 | - margin-left: 1130px; |
2928 | - } |
2929 | - .offset10 { |
2930 | - margin-left: 1030px; |
2931 | - } |
2932 | - .offset9 { |
2933 | - margin-left: 930px; |
2934 | - } |
2935 | - .offset8 { |
2936 | - margin-left: 830px; |
2937 | - } |
2938 | - .offset7 { |
2939 | - margin-left: 730px; |
2940 | - } |
2941 | - .offset6 { |
2942 | - margin-left: 630px; |
2943 | - } |
2944 | - .offset5 { |
2945 | - margin-left: 530px; |
2946 | - } |
2947 | - .offset4 { |
2948 | - margin-left: 430px; |
2949 | - } |
2950 | - .offset3 { |
2951 | - margin-left: 330px; |
2952 | - } |
2953 | - .offset2 { |
2954 | - margin-left: 230px; |
2955 | - } |
2956 | - .offset1 { |
2957 | - margin-left: 130px; |
2958 | - } |
2959 | - .row-fluid { |
2960 | - width: 100%; |
2961 | - *zoom: 1; |
2962 | - } |
2963 | - .row-fluid:before, |
2964 | - .row-fluid:after { |
2965 | - display: table; |
2966 | - content: ""; |
2967 | - } |
2968 | - .row-fluid:after { |
2969 | - clear: both; |
2970 | - } |
2971 | - .row-fluid [class*="span"] { |
2972 | - display: block; |
2973 | - float: left; |
2974 | - width: 100%; |
2975 | - min-height: 28px; |
2976 | - margin-left: 2.564102564%; |
2977 | - *margin-left: 2.510911074638298%; |
2978 | - -webkit-box-sizing: border-box; |
2979 | - -moz-box-sizing: border-box; |
2980 | - -ms-box-sizing: border-box; |
2981 | - box-sizing: border-box; |
2982 | - } |
2983 | - .row-fluid [class*="span"]:first-child { |
2984 | - margin-left: 0; |
2985 | - } |
2986 | - .row-fluid .span12 { |
2987 | - width: 100%; |
2988 | - *width: 99.94680851063829%; |
2989 | - } |
2990 | - .row-fluid .span11 { |
2991 | - width: 91.45299145300001%; |
2992 | - *width: 91.3997999636383%; |
2993 | - } |
2994 | - .row-fluid .span10 { |
2995 | - width: 82.905982906%; |
2996 | - *width: 82.8527914166383%; |
2997 | - } |
2998 | - .row-fluid .span9 { |
2999 | - width: 74.358974359%; |
3000 | - *width: 74.30578286963829%; |
3001 | - } |
3002 | - .row-fluid .span8 { |
3003 | - width: 65.81196581200001%; |
3004 | - *width: 65.7587743226383%; |
3005 | - } |
3006 | - .row-fluid .span7 { |
3007 | - width: 57.264957265%; |
3008 | - *width: 57.2117657756383%; |
3009 | - } |
3010 | - .row-fluid .span6 { |
3011 | - width: 48.717948718%; |
3012 | - *width: 48.6647572286383%; |
3013 | - } |
3014 | - .row-fluid .span5 { |
3015 | - width: 40.170940171000005%; |
3016 | - *width: 40.117748681638304%; |
3017 | - } |
3018 | - .row-fluid .span4 { |
3019 | - width: 31.623931624%; |
3020 | - *width: 31.5707401346383%; |
3021 | - } |
3022 | - .row-fluid .span3 { |
3023 | - width: 23.076923077%; |
3024 | - *width: 23.0237315876383%; |
3025 | - } |
3026 | - .row-fluid .span2 { |
3027 | - width: 14.529914530000001%; |
3028 | - *width: 14.4767230406383%; |
3029 | - } |
3030 | - .row-fluid .span1 { |
3031 | - width: 5.982905983%; |
3032 | - *width: 5.929714493638298%; |
3033 | - } |
3034 | - input, |
3035 | - textarea, |
3036 | - .uneditable-input { |
3037 | - margin-left: 0; |
3038 | - } |
3039 | - input.span12, |
3040 | - textarea.span12, |
3041 | - .uneditable-input.span12 { |
3042 | - width: 1160px; |
3043 | - } |
3044 | - input.span11, |
3045 | - textarea.span11, |
3046 | - .uneditable-input.span11 { |
3047 | - width: 1060px; |
3048 | - } |
3049 | - input.span10, |
3050 | - textarea.span10, |
3051 | - .uneditable-input.span10 { |
3052 | - width: 960px; |
3053 | - } |
3054 | - input.span9, |
3055 | - textarea.span9, |
3056 | - .uneditable-input.span9 { |
3057 | - width: 860px; |
3058 | - } |
3059 | - input.span8, |
3060 | - textarea.span8, |
3061 | - .uneditable-input.span8 { |
3062 | - width: 760px; |
3063 | - } |
3064 | - input.span7, |
3065 | - textarea.span7, |
3066 | - .uneditable-input.span7 { |
3067 | - width: 660px; |
3068 | - } |
3069 | - input.span6, |
3070 | - textarea.span6, |
3071 | - .uneditable-input.span6 { |
3072 | - width: 560px; |
3073 | - } |
3074 | - input.span5, |
3075 | - textarea.span5, |
3076 | - .uneditable-input.span5 { |
3077 | - width: 460px; |
3078 | - } |
3079 | - input.span4, |
3080 | - textarea.span4, |
3081 | - .uneditable-input.span4 { |
3082 | - width: 360px; |
3083 | - } |
3084 | - input.span3, |
3085 | - textarea.span3, |
3086 | - .uneditable-input.span3 { |
3087 | - width: 260px; |
3088 | - } |
3089 | - input.span2, |
3090 | - textarea.span2, |
3091 | - .uneditable-input.span2 { |
3092 | - width: 160px; |
3093 | - } |
3094 | - input.span1, |
3095 | - textarea.span1, |
3096 | - .uneditable-input.span1 { |
3097 | - width: 60px; |
3098 | - } |
3099 | - .thumbnails { |
3100 | - margin-left: -30px; |
3101 | - } |
3102 | - .thumbnails > li { |
3103 | - margin-left: 30px; |
3104 | - } |
3105 | - .row-fluid .thumbnails { |
3106 | - margin-left: 0; |
3107 | - } |
3108 | -} |
3109 | - |
3110 | -@media (max-width: 979px) { |
3111 | - body { |
3112 | - padding-top: 0; |
3113 | - } |
3114 | - .navbar-fixed-top, |
3115 | - .navbar-fixed-bottom { |
3116 | - position: static; |
3117 | - } |
3118 | - .navbar-fixed-top { |
3119 | - margin-bottom: 18px; |
3120 | - } |
3121 | - .navbar-fixed-bottom { |
3122 | - margin-top: 18px; |
3123 | - } |
3124 | - .navbar-fixed-top .navbar-inner, |
3125 | - .navbar-fixed-bottom .navbar-inner { |
3126 | - padding: 5px; |
3127 | - } |
3128 | - .navbar .container { |
3129 | - width: auto; |
3130 | - padding: 0; |
3131 | - } |
3132 | - .navbar .brand { |
3133 | - padding-right: 10px; |
3134 | - padding-left: 10px; |
3135 | - margin: 0 0 0 -5px; |
3136 | - } |
3137 | - .nav-collapse { |
3138 | - clear: both; |
3139 | - } |
3140 | - .nav-collapse .nav { |
3141 | - float: none; |
3142 | - margin: 0 0 9px; |
3143 | - } |
3144 | - .nav-collapse .nav > li { |
3145 | - float: none; |
3146 | - } |
3147 | - .nav-collapse .nav > li > a { |
3148 | - margin-bottom: 2px; |
3149 | - } |
3150 | - .nav-collapse .nav > .divider-vertical { |
3151 | - display: none; |
3152 | - } |
3153 | - .nav-collapse .nav .nav-header { |
3154 | - color: #999999; |
3155 | - text-shadow: none; |
3156 | - } |
3157 | - .nav-collapse .nav > li > a, |
3158 | - .nav-collapse .dropdown-menu a { |
3159 | - padding: 6px 15px; |
3160 | - font-weight: bold; |
3161 | - color: #999999; |
3162 | - -webkit-border-radius: 3px; |
3163 | - -moz-border-radius: 3px; |
3164 | - border-radius: 3px; |
3165 | - } |
3166 | - .nav-collapse .btn { |
3167 | - padding: 4px 10px 4px; |
3168 | - font-weight: normal; |
3169 | - -webkit-border-radius: 4px; |
3170 | - -moz-border-radius: 4px; |
3171 | - border-radius: 4px; |
3172 | - } |
3173 | - .nav-collapse .dropdown-menu li + li a { |
3174 | - margin-bottom: 2px; |
3175 | - } |
3176 | - .nav-collapse .nav > li > a:hover, |
3177 | - .nav-collapse .dropdown-menu a:hover { |
3178 | - background-color: #222222; |
3179 | - } |
3180 | - .nav-collapse.in .btn-group { |
3181 | - padding: 0; |
3182 | - margin-top: 5px; |
3183 | - } |
3184 | - .nav-collapse .dropdown-menu { |
3185 | - position: static; |
3186 | - top: auto; |
3187 | - left: auto; |
3188 | - display: block; |
3189 | - float: none; |
3190 | - max-width: none; |
3191 | - padding: 0; |
3192 | - margin: 0 15px; |
3193 | - background-color: transparent; |
3194 | - border: none; |
3195 | - -webkit-border-radius: 0; |
3196 | - -moz-border-radius: 0; |
3197 | - border-radius: 0; |
3198 | - -webkit-box-shadow: none; |
3199 | - -moz-box-shadow: none; |
3200 | - box-shadow: none; |
3201 | - } |
3202 | - .nav-collapse .dropdown-menu:before, |
3203 | - .nav-collapse .dropdown-menu:after { |
3204 | - display: none; |
3205 | - } |
3206 | - .nav-collapse .dropdown-menu .divider { |
3207 | - display: none; |
3208 | - } |
3209 | - .nav-collapse .navbar-form, |
3210 | - .nav-collapse .navbar-search { |
3211 | - float: none; |
3212 | - padding: 9px 15px; |
3213 | - margin: 9px 0; |
3214 | - border-top: 1px solid #222222; |
3215 | - border-bottom: 1px solid #222222; |
3216 | - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); |
3217 | - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); |
3218 | - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); |
3219 | - } |
3220 | - .navbar .nav-collapse .nav.pull-right { |
3221 | - float: none; |
3222 | - margin-left: 0; |
3223 | - } |
3224 | - .nav-collapse, |
3225 | - .nav-collapse.collapse { |
3226 | - height: 0; |
3227 | - overflow: hidden; |
3228 | - } |
3229 | - .navbar .btn-navbar { |
3230 | - display: block; |
3231 | - } |
3232 | - .navbar-static .navbar-inner { |
3233 | - padding-right: 10px; |
3234 | - padding-left: 10px; |
3235 | - } |
3236 | -} |
3237 | - |
3238 | -@media (min-width: 980px) { |
3239 | - .nav-collapse.collapse { |
3240 | - height: auto !important; |
3241 | - overflow: visible !important; |
3242 | - } |
3243 | -} |
3244 | |
3245 | === added file 'app/assets/stylesheets/juju-bootstrap.css' |
3246 | --- app/assets/stylesheets/juju-bootstrap.css 1970-01-01 00:00:00 +0000 |
3247 | +++ app/assets/stylesheets/juju-bootstrap.css 2013-06-26 14:26:26 +0000 |
3248 | @@ -0,0 +1,156 @@ |
3249 | +/* |
3250 | +To help gradually move away from bootstrap when so much of the application |
3251 | +relies on its styles, when you find a bootstrap specific class style copy the |
3252 | +__not overridden__ styles into this file. |
3253 | +*/ |
3254 | +.btn { |
3255 | + display: inline-block; |
3256 | + padding: 4px 10px 4px; |
3257 | + margin-bottom: 0; |
3258 | + font-size: 13px; |
3259 | + line-height: 18px; |
3260 | + color: #333333; |
3261 | + text-align: center; |
3262 | + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); |
3263 | + vertical-align: middle; |
3264 | + cursor: pointer; |
3265 | + background-color: #f5f5f5; |
3266 | + background-image: -ms-linear-gradient(top, #ffffff, #e6e6e6); |
3267 | + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); |
3268 | + background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); |
3269 | + background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); |
3270 | + background-image: linear-gradient(top, #ffffff, #e6e6e6); |
3271 | + background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); |
3272 | + background-repeat: repeat-x; |
3273 | + border: 1px solid #cccccc; |
3274 | + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); |
3275 | + border-color: #e6e6e6 #e6e6e6 #bfbfbf; |
3276 | + border-bottom-color: #b3b3b3; |
3277 | + -webkit-border-radius: 4px; |
3278 | + -moz-border-radius: 4px; |
3279 | + border-radius: 4px; |
3280 | + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0); |
3281 | + filter: progid:dximagetransform.microsoft.gradient(enabled=false); |
3282 | + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); |
3283 | + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); |
3284 | + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); |
3285 | +} |
3286 | + |
3287 | +.btn:hover { |
3288 | + color: #333333; |
3289 | + text-decoration: none; |
3290 | + background-color: #e6e6e6; |
3291 | + background-position: 0 -15px; |
3292 | + -webkit-transition: background-position 0.1s linear; |
3293 | + -moz-transition: background-position 0.1s linear; |
3294 | + -ms-transition: background-position 0.1s linear; |
3295 | + -o-transition: background-position 0.1s linear; |
3296 | + transition: background-position 0.1s linear; |
3297 | +} |
3298 | + |
3299 | +.btn-primary, .btn-primary:hover, .btn-warning, .btn-warning:hover, .btn-danger, .btn-danger:hover, .btn-success, .btn-success:hover, .btn-info, .btn-info:hover, .btn-inverse, .btn-inverse:hover { |
3300 | + color: #ffffff; |
3301 | + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); |
3302 | +} |
3303 | + |
3304 | +.btn-danger { |
3305 | + background-color: #da4f49; |
3306 | + background-image: -ms-linear-gradient(top, #ee5f5b, #bd362f); |
3307 | + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); |
3308 | + background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); |
3309 | + background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); |
3310 | + background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); |
3311 | + background-image: linear-gradient(top, #ee5f5b, #bd362f); |
3312 | + background-repeat: repeat-x; |
3313 | + border-color: #bd362f #bd362f #802420; |
3314 | + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); |
3315 | + filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#bd362f', GradientType=0); |
3316 | + filter: progid:dximagetransform.microsoft.gradient(enabled=false); |
3317 | +} |
3318 | + |
3319 | +.btn-danger:hover, .btn-danger:active, .btn-danger.active, .btn-danger.disabled, .btn-danger[disabled] { |
3320 | + background-color: #bd362f; |
3321 | +} |
3322 | + |
3323 | +.navbar .btn { |
3324 | + display: inline-block; |
3325 | + padding: 4px 10px 4px; |
3326 | + line-height: 18px; |
3327 | +} |
3328 | + |
3329 | +.navbar .dropdown-menu:after { |
3330 | + position: absolute; |
3331 | + top: -6px; |
3332 | + left: 10px; |
3333 | + display: inline-block; |
3334 | + border-right: 6px solid transparent; |
3335 | + border-bottom: 6px solid #ffffff; |
3336 | + border-left: 6px solid transparent; |
3337 | + content: ''; |
3338 | +} |
3339 | + |
3340 | +.navbar .dropdown-menu:before { |
3341 | + position: absolute; |
3342 | + top: -7px; |
3343 | + left: 9px; |
3344 | + display: inline-block; |
3345 | + border-right: 7px solid transparent; |
3346 | + border-bottom: 7px solid #ccc; |
3347 | + border-left: 7px solid transparent; |
3348 | + border-bottom-color: rgba(0, 0, 0, 0.2); |
3349 | + content: ''; |
3350 | +} |
3351 | + |
3352 | +.dropdown-menu { |
3353 | + position: absolute; |
3354 | + top: 100%; |
3355 | + left: 0; |
3356 | + z-index: 1000; |
3357 | + display: none; |
3358 | + float: left; |
3359 | + min-width: 160px; |
3360 | + padding: 4px 0; |
3361 | + margin: 1px 0 0; |
3362 | + list-style: none; |
3363 | + background-color: #ffffff; |
3364 | + border: 1px solid #ccc; |
3365 | + border: 1px solid rgba(0, 0, 0, 0.2); |
3366 | + -webkit-border-radius: 5px; |
3367 | + -moz-border-radius: 5px; |
3368 | + border-radius: 5px; |
3369 | + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); |
3370 | + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); |
3371 | + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); |
3372 | + -webkit-background-clip: padding-box; |
3373 | + -moz-background-clip: padding; |
3374 | + background-clip: padding-box; |
3375 | +} |
3376 | + |
3377 | +.open > .dropdown-menu { |
3378 | + display: block; |
3379 | +} |
3380 | + |
3381 | +.dropdown-menu a { |
3382 | + display: block; |
3383 | + padding: 3px 15px; |
3384 | + clear: both; |
3385 | + font-weight: normal; |
3386 | + line-height: 18px; |
3387 | + color: #333333; |
3388 | + white-space: nowrap; |
3389 | +} |
3390 | + |
3391 | +.icon-arrow-right { |
3392 | + background-position: -264px -96px; |
3393 | +} |
3394 | + |
3395 | +[class^="icon-"], [class*=" icon-"] { |
3396 | + display: inline-block; |
3397 | + width: 14px; |
3398 | + height: 14px; |
3399 | + line-height: 14px; |
3400 | + vertical-align: text-top; |
3401 | + background-image: url("../images/glyphicons-halflings.png"); |
3402 | + background-position: 14px 14px; |
3403 | + background-repeat: no-repeat; |
3404 | +} |
3405 | |
3406 | === modified file 'app/config-debug.js' |
3407 | --- app/config-debug.js 2013-05-29 16:50:27 +0000 |
3408 | +++ app/config-debug.js 2013-06-26 14:26:26 +0000 |
3409 | @@ -48,5 +48,9 @@ |
3410 | // There is also a hotkey to toggle the simulator. |
3411 | simulateEvents: true, |
3412 | readOnly: false, |
3413 | + // Enable Google Analytics usage and calls. Also implies using cookies. |
3414 | + // For the debug configuration, analytics should generally be false to |
3415 | + // prevent muddying the gathered statistics. |
3416 | + useAnalytics: false, |
3417 | login_help: 'For this demonstration, use the password "admin" to connect.' |
3418 | }; |
3419 | |
3420 | === modified file 'app/config-prod.js' |
3421 | --- app/config-prod.js 2013-05-28 12:52:54 +0000 |
3422 | +++ app/config-prod.js 2013-06-26 14:26:26 +0000 |
3423 | @@ -47,6 +47,10 @@ |
3424 | // You can also use the :flags:/simulateEvents feature flag. |
3425 | simulateEvents: false, |
3426 | readOnly: false, |
3427 | + // Enable Google Analytics usage and calls. Also implies using cookies. |
3428 | + // XXX: BradCrittenden 2013-06-10 bug=1189502: set to 'true' by default |
3429 | + // only after this bug is resolved, exposing the setting in the charm. |
3430 | + useAnalytics: false, |
3431 | login_help: ( |
3432 | 'The password is the admin-secret from the Juju environment. This can ' + |
3433 | 'often be found by looking in ~/.juju/environments.yaml.') |
3434 | |
3435 | === modified file 'app/index.html' |
3436 | --- app/index.html 2013-05-28 18:53:33 +0000 |
3437 | +++ app/index.html 2013-06-26 14:26:26 +0000 |
3438 | @@ -42,15 +42,32 @@ |
3439 | <link rel="stylesheet" href="/juju-ui/assets/combined-css/all-static.css"> |
3440 | <link rel="stylesheet" href="/juju-ui/assets/juju-gui.css"> |
3441 | <link rel="stylesheet" href="/juju-ui/assets/sprite.css"> |
3442 | + |
3443 | <!--[if lt IE 9]> |
3444 | <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> |
3445 | <![endif]--> |
3446 | + |
3447 | + <!-- Set up Google analytics async tracking. |
3448 | + If the domain is set to 'jujucharms.com' as you'd expect, the tracker |
3449 | + does not work for deployments outside of our demo site. |
3450 | + --> |
3451 | + <script type="text/javascript"> |
3452 | + var _gaq = _gaq || []; |
3453 | + window._gaq = _gaq; |
3454 | + window.ga_id = 'UA-41463568-2'; |
3455 | + _gaq.push(['_setAccount', window.ga_id]); |
3456 | + _gaq.push (['_gat._anonymizeIp']); |
3457 | + _gaq.push(['_setDomainName', 'none']); |
3458 | + _gaq.push(['_setAllowLinker', true]); |
3459 | + _gaq.push(['_trackPageview']); |
3460 | + </script> |
3461 | + |
3462 | </head> |
3463 | |
3464 | <body> |
3465 | <!-- This <img> tag is here just to force early loading of the background |
3466 | - image so it displays more quickly. This makes a large improvment to the |
3467 | - way the app looks while loading on a slow connection. --> |
3468 | + image so it displays more quickly. This makes a large improvement to |
3469 | + the way the app looks while loading on a slow connection. --> |
3470 | <img src="/juju-ui/assets/images/pattern_tile.png" style="display: none;"> |
3471 | |
3472 | <div id="full-screen-mask" class="crosshatch-background"> |
3473 | @@ -89,58 +106,49 @@ |
3474 | </div> |
3475 | </div> |
3476 | <div id="notifier-box"></div> |
3477 | + <div class="cookie-policy" style="display:none;"> |
3478 | + <div class="wrapper"> |
3479 | + <a href="" class="link-cta">Close</a> |
3480 | + <p> |
3481 | + We use cookies to improve your experience. By your continued use of |
3482 | + this application you accept such use. To change your settings please |
3483 | + <a href="http://www.ubuntu.com/privacy-policy#cookies">see our policy</a> |
3484 | + </p> |
3485 | + </div> |
3486 | + </div> |
3487 | <div id="viewport-wrapper"> |
3488 | <div id="vp-left-border"></div> |
3489 | <div id="viewport"> |
3490 | - <div class="navbar"> |
3491 | + <div class="navbar"> |
3492 | + <div class="navbar-inner"> |
3493 | <div id="nav-brand-env"> |
3494 | - <span> |
3495 | - <a class="brand" href="/"> |
3496 | - <i class="sprite juju_logo" title="Juju GUI"></i> |
3497 | - </a> |
3498 | - </span> |
3499 | - <span class="nav-container"> |
3500 | - <span class="nav-section"> |
3501 | - <i class="sprite environment_icon"> </i> |
3502 | - <span id="environment-name" draggable="true"></span> |
3503 | - <span id="provider-type" class="provider-type"></span> |
3504 | - </span> |
3505 | - </span> |
3506 | - </div> |
3507 | - <div id="nav-alerts-charms"> |
3508 | - <span class="nav-container"> |
3509 | - <span class="nav-section"> |
3510 | - <i class="sprite alert_icon"></i> |
3511 | - Alerts |
3512 | - <span id="notifications"></span> |
3513 | - </span> |
3514 | - </span> |
3515 | - <span class="nav-container"> |
3516 | - <span class="nav-section active-border"> |
3517 | - <div id="logout-trigger">Logout</div> |
3518 | - </span> |
3519 | - </span> |
3520 | - <span class="nav-container" id="charm-search-trigger-container"> |
3521 | - <span class="nav-section active-border"> |
3522 | - <span id="charm-search-trigger"> |
3523 | - <i id="charm-search-icon" class="sprite charm_icon"></i> |
3524 | - Charms |
3525 | - <i id="charm-search-chevron" class="sprite chevron_down"></i> |
3526 | - </span> |
3527 | - <input type="text" id="charm-search-field" |
3528 | - required="required" placeholder="Search for a charm" /> |
3529 | - </span> |
3530 | - </span> |
3531 | - </div> |
3532 | - </div> |
3533 | - <div id="content"> |
3534 | - <div id="shortcut-help" style="display:none"></div> |
3535 | - <div id="subapp-browser-min" style="display: none;"></div> |
3536 | - <div id="subapp-browser"></div> |
3537 | - <div id="main"> |
3538 | - </div> <!-- /container --> |
3539 | - </div> |
3540 | - |
3541 | + <a class="brand" href="/"> |
3542 | + <i class="sprite juju_logo_dark" title="Juju GUI"></i> |
3543 | + </a> |
3544 | + <div id="environment-switcher"> |
3545 | + <i class="sprite environment_icon"> </i> |
3546 | + <span id="environment-name" draggable="true"></span> |
3547 | + <span id="provider-type" class="provider-type"></span> |
3548 | + </div> |
3549 | + </div> |
3550 | + <ul class="nav"> |
3551 | + <li> |
3552 | + <span id="notifications"></span> |
3553 | + Alerts |
3554 | + </li> |
3555 | + <li> |
3556 | + <a href="" id="logout-trigger">Logout</a> |
3557 | + </li> |
3558 | + </ul> |
3559 | + </div> |
3560 | + </div> |
3561 | + <div id="content"> |
3562 | + <div id="shortcut-help" style="display:none"></div> |
3563 | + <div id="subapp-browser-min" style="display: none;"></div> |
3564 | + <div id="subapp-browser"></div> |
3565 | + <div id="main"> |
3566 | + </div> <!-- /container --> |
3567 | + </div> |
3568 | </div> |
3569 | <div id="vp-right-border"></div> |
3570 | </div> |
3571 | @@ -349,8 +357,26 @@ |
3572 | // We need to activate the hotkeys when running the application |
3573 | // in production. Unit tests should call it manually. |
3574 | app.activateHotkeys(); |
3575 | + |
3576 | + if (!juju_config.useAnalytics) { |
3577 | + window['ga-disable-' + window.ga_id] = true; |
3578 | + } |
3579 | }); |
3580 | + |
3581 | }; |
3582 | </script> |
3583 | + |
3584 | + <script type="text/javascript"> |
3585 | + (function() { |
3586 | + var ga = document.createElement('script'); |
3587 | + ga.type = 'text/javascript'; ga.async = true; |
3588 | + ga.src = ('https:' == document.location.protocol ? |
3589 | + 'https://ssl' : 'http://www') + |
3590 | + '.google-analytics.com/ga.js'; |
3591 | + var s = document.getElementsByTagName('script')[0]; |
3592 | + s.parentNode.insertBefore(ga, s); |
3593 | + })(); |
3594 | + </script> |
3595 | + |
3596 | </body> |
3597 | </html> |
3598 | |
3599 | === modified file 'app/models/browser.js' |
3600 | --- app/models/browser.js 2013-05-17 14:51:05 +0000 |
3601 | +++ app/models/browser.js 2013-06-26 14:26:26 +0000 |
3602 | @@ -30,7 +30,7 @@ |
3603 | var models = Y.namespace('juju.models'), |
3604 | ns = Y.namespace('juju.models.browser'); |
3605 | |
3606 | - /** |
3607 | + /* |
3608 | * The filters are hard coded for now but will need to be updated. The |
3609 | * *right* place for them to live isn't obvious at the moment so they may |
3610 | * move. There are notes for an API call to provide a list, but we don't |
3611 | @@ -86,6 +86,31 @@ |
3612 | }, |
3613 | |
3614 | /** |
3615 | + Clears all filter data |
3616 | + |
3617 | + @method _clear |
3618 | + @private |
3619 | + */ |
3620 | + _clear: function() { |
3621 | + this.setAttrs({ |
3622 | + categories: [], |
3623 | + provider: [], |
3624 | + series: [], |
3625 | + text: '', |
3626 | + type: [] |
3627 | + }); |
3628 | + }, |
3629 | + |
3630 | + /** |
3631 | + Resets the filter |
3632 | + |
3633 | + @method reset |
3634 | + */ |
3635 | + reset: function() { |
3636 | + this._clear(); |
3637 | + this._setDefaults(); |
3638 | + }, |
3639 | + /** |
3640 | Given the current filters, generate a query string to use for api |
3641 | calls. |
3642 | |
3643 | |
3644 | === modified file 'app/models/charm.js' |
3645 | --- app/models/charm.js 2013-05-29 15:19:30 +0000 |
3646 | +++ app/models/charm.js 2013-06-26 14:26:26 +0000 |
3647 | @@ -323,18 +323,22 @@ |
3648 | |
3649 | |
3650 | /** |
3651 | - * Model to represent the Charms from the Charmworld1 Api. |
3652 | + * Model to represent the Charms from the Charmworld2 Api. |
3653 | * |
3654 | * @class BrowserCharm |
3655 | * @extends {Charm} |
3656 | * |
3657 | */ |
3658 | models.BrowserCharm = Y.Base.create('browser-charm', Charm, [], { |
3659 | + // Only care about at most, this number of related charms per interface. |
3660 | + maxRelatedCharms: 5, |
3661 | + |
3662 | /** |
3663 | - * Load the recent commits into a format we can use nicely. |
3664 | - * |
3665 | - * @method _loadRecentCommits |
3666 | - * |
3667 | + |
3668 | + Load the recent commits into a format we can use nicely. |
3669 | + |
3670 | + @method _loadRecentCommits |
3671 | + |
3672 | */ |
3673 | _loadRecentCommits: function() { |
3674 | var source = this.get('code_source'), |
3675 | @@ -375,6 +379,28 @@ |
3676 | }, |
3677 | |
3678 | /** |
3679 | + Given the set of data for relatedCharms, make it compatible with the |
3680 | + model api to be used in the charm-token widget, for example. |
3681 | + |
3682 | + @method _convertRelatedData |
3683 | + @param {Object} data a related charm object. |
3684 | + |
3685 | + */ |
3686 | + _convertRelatedData: function(data) { |
3687 | + return { |
3688 | + // Only show the icon if it has one and the charm has been reviewed to |
3689 | + // have a safe icon. |
3690 | + shouldShowIcon: data.has_icon && data.is_approved, |
3691 | + id: data.id, |
3692 | + mainCategory: data.categories[0], |
3693 | + name: data.name, |
3694 | + recent_commit_count: data.commits_in_past_30_days, |
3695 | + recent_download_count: data.downloads_in_past_30_days, |
3696 | + weight: data.weight |
3697 | + }; |
3698 | + }, |
3699 | + |
3700 | + /** |
3701 | * Initializer |
3702 | * |
3703 | * @method initializer |
3704 | @@ -384,6 +410,57 @@ |
3705 | if (cfg && cfg.downloads_in_past_30_days) { |
3706 | this.set('recent_download_count', cfg.downloads_in_past_30_days); |
3707 | } |
3708 | + }, |
3709 | + |
3710 | + /** |
3711 | + Build the relatedCharms attribute from api data |
3712 | + |
3713 | + @method buildRelatedCharms |
3714 | + @param {Object} provides the list of provides interfaces/charms. |
3715 | + @param {Object} requires the list of requires interfaces/charms. |
3716 | + |
3717 | + */ |
3718 | + buildRelatedCharms: function(provides, requires) { |
3719 | + var charms = { |
3720 | + all: {}, |
3721 | + provides: {}, |
3722 | + requires: {} |
3723 | + }; |
3724 | + |
3725 | + var buildWeightedList = function(relationName, relationData, scope) { |
3726 | + Y.Object.each(relationData, function(face, key) { |
3727 | + // The relations are in the order of score, so we can limit them right |
3728 | + // off the bat. |
3729 | + charms[relationName][key] = face.slice(0, this.maxRelatedCharms); |
3730 | + charms[relationName][key].forEach(function(relation, idx) { |
3731 | + // Update the related object with the converted version so that it's |
3732 | + // follows the model ATTRS |
3733 | + charms[relationName][key][idx] = this._convertRelatedData(relation); |
3734 | + // Then track the highest provides charm to be in the running for |
3735 | + // overall most weighted related charm. |
3736 | + charms.all[relation.id] = charms[relationName][key][idx]; |
3737 | + }, scope); |
3738 | + }, scope); |
3739 | + }; |
3740 | + |
3741 | + buildWeightedList('provides', provides, this); |
3742 | + buildWeightedList('requires', requires, this); |
3743 | + |
3744 | + // Find the highest weight charms, but make sure there are no |
3745 | + // duplicates. We build the object to index on key and remove dupes, |
3746 | + // then we get a list of results and sort them by weight, grabbing the |
3747 | + // top set. |
3748 | + var allCharmsList = Y.Object.values(charms.all); |
3749 | + |
3750 | + allCharmsList.sort(function(charm1, charm2) { |
3751 | + return charm2.weight - charm1.weight; |
3752 | + }); |
3753 | + |
3754 | + this.set('relatedCharms', { |
3755 | + overall: allCharmsList.slice(0, this.maxRelatedCharms), |
3756 | + provides: charms.provides, |
3757 | + requires: charms.requires |
3758 | + }); |
3759 | } |
3760 | }, { |
3761 | ATTRS: { |
3762 | @@ -461,19 +538,22 @@ |
3763 | return tmp.join('/'); |
3764 | } |
3765 | }, |
3766 | - /** |
3767 | - Does this charm have an icon file. Helper used for template rendering |
3768 | - decisions. |
3769 | - |
3770 | - */ |
3771 | - hasIcon: { |
3772 | + shouldShowIcon: { |
3773 | /** |
3774 | - @method hasIcon.valueFn |
3775 | - @return {Boolean} Does the Charm have an icon file. |
3776 | + Should this charm display its icon. Helper used for template |
3777 | + rendering decisions. |
3778 | + |
3779 | + @method shouldShowIcon.valueFn |
3780 | + @return {Boolean} Does the charm have an icon that should be shown? |
3781 | |
3782 | */ |
3783 | valueFn: function() { |
3784 | - return this.get('files').indexOf('icon.svg') !== -1 ? true : false; |
3785 | + if (this.get('files').indexOf('icon.svg') !== -1 && |
3786 | + this.get('is_approved')) { |
3787 | + return true; |
3788 | + } else { |
3789 | + return false; |
3790 | + } |
3791 | } |
3792 | }, |
3793 | is_approved: {}, |
3794 | @@ -493,8 +573,33 @@ |
3795 | return val; |
3796 | } |
3797 | }, |
3798 | + /** |
3799 | + The mainCategory is a helper since we can only show one icon per |
3800 | + charm, but we permit multiple categories. An initial pass just grabs |
3801 | + the first category to use as an icon if required. |
3802 | + |
3803 | + @attribute mainCategory |
3804 | + @default null |
3805 | + @type {String} |
3806 | + |
3807 | + */ |
3808 | + mainCategory: { |
3809 | + /** |
3810 | + @method mainCategory.valueFn |
3811 | + @return {String|Null} If a category is found its value else null. |
3812 | + |
3813 | + */ |
3814 | + valueFn: function() { |
3815 | + var categories = this.get('categories'); |
3816 | + if (categories.length > 0) { |
3817 | + return categories[0]; |
3818 | + } else { |
3819 | + return null; |
3820 | + } |
3821 | + } |
3822 | + }, |
3823 | maintainer: {}, |
3824 | - /** |
3825 | + /* |
3826 | API related metdata information for this charm object. |
3827 | |
3828 | This includes information such as related charms calculated by the |
3829 | @@ -521,7 +626,7 @@ |
3830 | /** |
3831 | * This attr is a mapper to the relations ATTR in the new API. It's |
3832 | * provided for backwards compatibility with the original Charm model. |
3833 | - * This can be removed when Charmworld1 is the one true model used in |
3834 | + * This can be removed when Charmworld2 is the one true model used in |
3835 | * all Juju Gui code. |
3836 | * |
3837 | * @attribute provides |
3838 | @@ -605,13 +710,28 @@ |
3839 | return 0; |
3840 | } |
3841 | }, |
3842 | + /** |
3843 | + The related charms object is three parts for use in our situations. |
3844 | + The keys are |
3845 | + - overall: the top scored related charms regardless of interface or |
3846 | + provide/requires |
3847 | + - provides: a nested object of the related charms for each provide |
3848 | + interface |
3849 | + - requires: a nested object of the related charms for each require |
3850 | + interface |
3851 | + @attribute relatedCharms |
3852 | + @default undefined |
3853 | + @type {Object} |
3854 | + |
3855 | + */ |
3856 | + relatedCharms: {}, |
3857 | relations: {}, |
3858 | |
3859 | /** |
3860 | * This attr is a mapper to the relations ATTR in the new API. It's |
3861 | * provided for backwards compatibility with the original Charm model. |
3862 | * |
3863 | - * This can be removed when Charmworld1 is the one true model used in |
3864 | + * This can be removed when Charmworld2 is the one true model used in |
3865 | * all Juju Gui code. |
3866 | * |
3867 | * @attribute requires |
3868 | |
3869 | === modified file 'app/models/handlers.js' |
3870 | --- app/models/handlers.js 2013-05-17 14:51:05 +0000 |
3871 | +++ app/models/handlers.js 2013-06-26 14:26:26 +0000 |
3872 | @@ -97,7 +97,7 @@ |
3873 | }; |
3874 | models.utils = utils; // Exported for testing purposes. |
3875 | |
3876 | - /** |
3877 | + /* |
3878 | Each handler is called passing the db instance, the action to be |
3879 | performed ("add", "change" or "remove"), the change coming from |
3880 | the environment, and a (optional) kind identifying what will be |
3881 | @@ -133,7 +133,7 @@ |
3882 | } else { |
3883 | data = change; |
3884 | } |
3885 | - modelList.process_delta(action, data); |
3886 | + modelList.process_delta(action, data, db); |
3887 | }, |
3888 | |
3889 | /** |
3890 | @@ -164,7 +164,7 @@ |
3891 | public_address: change.PublicAddress |
3892 | }; |
3893 | db.units.process_delta(action, unitData); |
3894 | - db.machines.process_delta(action, machineData); |
3895 | + db.machines.process_delta(action, machineData, db); |
3896 | }, |
3897 | |
3898 | /** |
3899 | |
3900 | === modified file 'app/models/models.js' |
3901 | --- app/models/models.js 2013-05-17 14:51:05 +0000 |
3902 | +++ app/models/models.js 2013-06-26 14:26:26 +0000 |
3903 | @@ -70,6 +70,8 @@ |
3904 | Y.each(data, function(value, key) { |
3905 | instance[key] = value; |
3906 | }); |
3907 | + // Lazy model lists don't fire change events |
3908 | + list.fire('change'); |
3909 | } |
3910 | } |
3911 | } |
3912 | @@ -80,6 +82,7 @@ |
3913 | } else { |
3914 | console.warn('Unknown change kind in _process_delta:', action); |
3915 | } |
3916 | + return instance; |
3917 | }; |
3918 | |
3919 | /** |
3920 | @@ -148,6 +151,9 @@ |
3921 | /** |
3922 | Dynamically calculate a display name that accounts for Juju Core name |
3923 | prefixes. |
3924 | + |
3925 | + @attribute displayName |
3926 | + @type {String} |
3927 | */ |
3928 | getter: function() { |
3929 | return this.get('id').replace('service-', ''); |
3930 | @@ -253,8 +259,21 @@ |
3931 | return name.replace('unit-', '').replace(/^(.+)-(\d+)$/, '$1/$2'); |
3932 | }, |
3933 | |
3934 | - process_delta: function(action, data) { |
3935 | - _process_delta(this, action, data, {relation_errors: {}}); |
3936 | + process_delta: function(action, data, db) { |
3937 | + var instance = _process_delta(this, action, data, {relation_errors: {}}); |
3938 | + if (!instance || !db) {return;} |
3939 | + // Apply this action for this instance to all service models as well. |
3940 | + // In the future we can transition from using db.units to always |
3941 | + // looking at db.services[serviceId].units |
3942 | + var service = db.services.getById(instance.service); |
3943 | + if (!service) { return; } |
3944 | + // Get the unit list for this service. (lazy) |
3945 | + var unitList = service.get('units'); |
3946 | + if (!unitList) { |
3947 | + unitList = new models.ServiceUnitList(); |
3948 | + service.set('units', unitList); |
3949 | + } |
3950 | + _process_delta(unitList, action, data, {relation_errors: {}}); |
3951 | }, |
3952 | |
3953 | _setDefaultsAndCalculatedValues: function(obj) { |
3954 | @@ -321,8 +340,15 @@ |
3955 | var aggregate = this.get_informative_states_for_service(service); |
3956 | var sum = Y.Array.reduce( |
3957 | Y.Object.values(aggregate), 0, function(a, b) {return a + b;}); |
3958 | + var previous_unit_count = service.get('unit_count'); |
3959 | service.set('unit_count', sum); |
3960 | service.set('aggregated_status', aggregate); |
3961 | + |
3962 | + // Set Google Analytics tracking event. |
3963 | + if (previous_unit_count !== sum && window._gaq) { |
3964 | + window._gaq.push(['_trackEvent', 'Service Stats', 'Update', |
3965 | + service.get('id'), sum]); |
3966 | + } |
3967 | }, |
3968 | ATTRS: {} |
3969 | }); |
3970 | |
3971 | === modified file 'app/modules-debug.js' |
3972 | --- app/modules-debug.js 2013-05-24 14:10:58 +0000 |
3973 | +++ app/modules-debug.js 2013-06-26 14:26:26 +0000 |
3974 | @@ -42,6 +42,11 @@ |
3975 | // Don't load YUI CSS from YUI servers. |
3976 | fetchCSS: false, |
3977 | |
3978 | + // Do not attempt to dispatch a new route when an anchor tag appears in the |
3979 | + // url. This is intended to keep charm details from reloading on tab |
3980 | + // selection in the browser. |
3981 | + navigateOnHash: false, |
3982 | + |
3983 | groups: { |
3984 | gallery: { |
3985 | modules: { |
3986 | @@ -101,12 +106,18 @@ |
3987 | } |
3988 | } |
3989 | }, |
3990 | - |
3991 | filesaver: { |
3992 | modules: { |
3993 | 'FileSaver': { |
3994 | fullpath: '/juju-ui/assets/javascripts/FileSaver.js' |
3995 | } |
3996 | + }, |
3997 | + observe: { |
3998 | + modules: { |
3999 | + 'observe': { |
4000 | + fullpath: '/juju-ui/assets/javascripts/Object.observe.poly.js' |
4001 | + } |
4002 | + } |
4003 | } |
4004 | }, |
4005 | |
4006 | @@ -134,6 +145,10 @@ |
4007 | fullpath: '/juju-ui/widgets/overlay-indicator.js' |
4008 | }, |
4009 | |
4010 | + 'browser-sharing-widget': { |
4011 | + fullpath: '/juju-ui/widgets/sharing-widget.js' |
4012 | + }, |
4013 | + |
4014 | 'browser-search-widget': { |
4015 | fullpath: '/juju-ui/widgets/charm-search.js' |
4016 | }, |
4017 | @@ -145,7 +160,9 @@ |
4018 | 'juju-inspector-widget': { |
4019 | fullpath: '/juju-ui/widgets/inspector-widget.js' |
4020 | }, |
4021 | - |
4022 | + 'juju-databinding': { |
4023 | + fullpath: '/juju-ui/views/databinding.js' |
4024 | + }, |
4025 | 'reconnecting-websocket': { |
4026 | fullpath: '/juju-ui/assets/javascripts/reconnecting-websocket.js' |
4027 | }, |
4028 | @@ -158,6 +175,10 @@ |
4029 | fullpath: '/juju-ui/assets/javascripts/app-subapp-extension.js' |
4030 | }, |
4031 | |
4032 | + 'app-cookies-extension': { |
4033 | + fullpath: '/juju-ui/assets/javascripts/app-cookies-extension.js' |
4034 | + }, |
4035 | + |
4036 | 'sub-app': { |
4037 | fullpath: '/juju-ui/assets/javascripts/sub-app.js' |
4038 | }, |
4039 | @@ -243,6 +264,10 @@ |
4040 | fullpath: '/juju-ui/templates.js' |
4041 | }, |
4042 | |
4043 | + 'juju-view-container': { |
4044 | + fullpath: '/juju-ui/views/view-container.js' |
4045 | + }, |
4046 | + |
4047 | 'juju-views': { |
4048 | use: [ |
4049 | 'handlebars', |
4050 | @@ -323,6 +348,10 @@ |
4051 | fullpath: '/juju-ui/store/charm.js' |
4052 | }, |
4053 | |
4054 | + 'juju-websocket-logging': { |
4055 | + fullpath: '/juju-ui/websocket-logging.js' |
4056 | + }, |
4057 | + |
4058 | 'juju-controllers': { |
4059 | use: [ |
4060 | 'juju-env', |
4061 | |
4062 | === modified file 'app/store/charm.js' |
4063 | --- app/store/charm.js 2013-05-29 17:42:37 +0000 |
4064 | +++ app/store/charm.js 2013-06-26 14:26:26 +0000 |
4065 | @@ -157,12 +157,12 @@ |
4066 | /** |
4067 | * Api helper for the updated charmworld api v1. |
4068 | * |
4069 | - * @class Charmworld1 |
4070 | + * @class Charmworld2 |
4071 | * @extends {Base} |
4072 | * |
4073 | */ |
4074 | - ns.Charmworld1 = Y.Base.create('charmworld1', Y.Base, [], { |
4075 | - _apiRoot: 'api/1', |
4076 | + ns.Charmworld2 = Y.Base.create('charmworld2', Y.Base, [], { |
4077 | + _apiRoot: 'api/2', |
4078 | |
4079 | /** |
4080 | * Send the actual request and handle response from the api. |
4081 | @@ -370,6 +370,25 @@ |
4082 | } |
4083 | |
4084 | this._makeRequest('charms/interesting', callbacks); |
4085 | + }, |
4086 | + |
4087 | + /** |
4088 | + Fetch the related charm info from the charmworld api. |
4089 | + |
4090 | + @method related |
4091 | + @param {String} charmID The charm to find related charms for. |
4092 | + @param {Object} callbacks The success/failure callbacks to use. |
4093 | + @param {Object} bindscope An object scope to perform callbacks in. |
4094 | + @return {Object} data loaded from the api call. |
4095 | + |
4096 | + */ |
4097 | + related: function(charmID, callbacks, bindScope) { |
4098 | + var endpoint = 'charm/' + charmID + '/related'; |
4099 | + if (bindScope) { |
4100 | + callbacks.success = Y.bind(callbacks.success, bindScope); |
4101 | + callbacks.failure = Y.bind(callbacks.failure, bindScope); |
4102 | + } |
4103 | + this._makeRequest(endpoint, callbacks); |
4104 | } |
4105 | }, { |
4106 | ATTRS: { |
4107 | @@ -384,6 +403,9 @@ |
4108 | apiHost: { |
4109 | required: true, |
4110 | setter: function(val) { |
4111 | + if (val && !val.match(/\/$/)) { |
4112 | + val = val + '/'; |
4113 | + } |
4114 | // Make sure we update the datasource if our apiHost changes. |
4115 | var source = val + this._apiRoot + '/'; |
4116 | this.set('datasource', new Y.DataSource.IO({ source: source })); |
4117 | |
4118 | === modified file 'app/store/env/fakebackend.js' |
4119 | --- app/store/env/fakebackend.js 2013-05-22 14:14:04 +0000 |
4120 | +++ app/store/env/fakebackend.js 2013-06-26 14:26:26 +0000 |
4121 | @@ -263,7 +263,9 @@ |
4122 | }, |
4123 | |
4124 | /** |
4125 | - Log out. If already logged out, no error is raised. |
4126 | + Log out. If already logged out, no error is raised. |
4127 | + @method logout |
4128 | + @return {undefined} Nothing. |
4129 | */ |
4130 | logout: function() { |
4131 | this.set('authenticated', false); |
4132 | @@ -287,7 +289,7 @@ |
4133 | configYAML: The charm configuration options, expressed as a YAML |
4134 | string. You may provide only one of config or configYAML. |
4135 | unitCount: The number of units to be deployed. |
4136 | - @return {undefined} Get the result from the callback. |
4137 | + @return {undefined} All results are passed to the callback. |
4138 | */ |
4139 | deploy: function(charmId, callback, options) { |
4140 | if (!this.get('authenticated')) { |
4141 | @@ -300,9 +302,7 @@ |
4142 | this._loadCharm( |
4143 | charmId, |
4144 | { |
4145 | - /** |
4146 | - Deploy the successfully-obtained charm. |
4147 | - */ |
4148 | + // On success deploy the successfully-obtained charm. |
4149 | success: function(charm) { |
4150 | self._deployFromCharm(charm, callback, options); |
4151 | }, |
4152 | @@ -312,6 +312,48 @@ |
4153 | }, |
4154 | |
4155 | /** |
4156 | + Set the given service to use the given charm, optionally forcing units in |
4157 | + error state to use the charm. |
4158 | + |
4159 | + @method setCharm |
4160 | + @param {String} serviceName The name of the service to set. |
4161 | + @param {String} charmId The charm to use. |
4162 | + @param {Boolean} force Whether or not to force the issue. |
4163 | + @param {Function} callback A call that will receive an object, potentially |
4164 | + with an "error" attribute containing a string describing the problem. |
4165 | + @return {undefined} All results are passed to the callback. |
4166 | + */ |
4167 | + setCharm: function(serviceName, charmId, force, callback) { |
4168 | + if (!this.get('authenticated')) { |
4169 | + return callback(UNAUTHENTICATEDERROR); |
4170 | + } |
4171 | + var self = this; |
4172 | + var service = this.db.services.getById(serviceName); |
4173 | + if (!service) { |
4174 | + return callback({error: 'Service "' + serviceName + '" not found.'}); |
4175 | + } |
4176 | + var serviceInError = this.db.units.get_units_for_service(service) |
4177 | + .some(function(unit) { |
4178 | + return (/error/).test(unit.agent_state); |
4179 | + }); |
4180 | + if (serviceInError && !force) { |
4181 | + return callback({error: 'Cannot set charm on a service with units in ' + |
4182 | + 'error without the force flag.'}); |
4183 | + } |
4184 | + this._loadCharm( |
4185 | + charmId, |
4186 | + { |
4187 | + success: function(charm) { |
4188 | + service.set('charm', charm.get('id')); |
4189 | + self.changes.services[service.get('id')] = [service, true]; |
4190 | + callback({}); |
4191 | + }, |
4192 | + failure: callback |
4193 | + } |
4194 | + ); |
4195 | + }, |
4196 | + |
4197 | + /** |
4198 | Get a charm from a URL, via charmStore and/or db. Uses callbacks. |
4199 | |
4200 | @method _loadCharm |
4201 | @@ -343,18 +385,15 @@ |
4202 | this.get('charmStore').loadByPath( |
4203 | charmIdParts.charm_store_path, |
4204 | { |
4205 | - /** |
4206 | - Convert the charm data to a charm and use the success callback. |
4207 | - */ |
4208 | + // Convert the charm data to a charm and use the success |
4209 | + // callback. |
4210 | success: function(data) { |
4211 | var charm = self._getCharmFromData(data); |
4212 | if (callbacks.success) { |
4213 | callbacks.success(charm); |
4214 | } |
4215 | }, |
4216 | - /** |
4217 | - Inform the caller of an error using the charm store. |
4218 | - */ |
4219 | + // Inform the caller of an error using the charm store. |
4220 | failure: function(e) { |
4221 | // This is most likely an IOError stemming from an |
4222 | // invalid charm pointing to a bad URL and a read of a |
4223 | @@ -399,6 +438,7 @@ |
4224 | /** |
4225 | Deploy a charm, given the charm, a callback, and options. |
4226 | |
4227 | + @method _deployFromCharm |
4228 | @param {Object} charm The charm to be deployed, from the db. |
4229 | @param {Function} callback A call that will receive an object either |
4230 | with an "error" attribute containing a string describing the problem, |
4231 | |
4232 | === modified file 'app/store/env/go.js' |
4233 | --- app/store/env/go.js 2013-05-21 16:30:38 +0000 |
4234 | +++ app/store/env/go.js 2013-06-26 14:26:26 +0000 |
4235 | @@ -388,6 +388,59 @@ |
4236 | }, |
4237 | |
4238 | /** |
4239 | + Set a service's charm. |
4240 | + |
4241 | + @method setCharm |
4242 | + @param {String} charm_url The URL of the charm. |
4243 | + @param {String} service_name The name of the service to be deployed. |
4244 | + @param {Function} callback A callable that must be called once the |
4245 | + operation is performed. |
4246 | + @return {undefined} Sends a message to the server only. |
4247 | + */ |
4248 | + setCharm: function(service_name, charm_url, force, callback) { |
4249 | + var intermediateCallback = null; |
4250 | + if (callback) { |
4251 | + intermediateCallback = Y.bind(this.handleSetCharm, this, |
4252 | + callback, service_name, charm_url); |
4253 | + } |
4254 | + this._send_rpc( |
4255 | + { Type: 'Client', |
4256 | + Request: 'ServiceSetCharm', |
4257 | + Params: { |
4258 | + ServiceName: service_name, |
4259 | + CharmUrl: charm_url, |
4260 | + Force: force |
4261 | + } |
4262 | + }, |
4263 | + intermediateCallback |
4264 | + ); |
4265 | + }, |
4266 | + |
4267 | + /** |
4268 | + Transform the data returned from juju-core 'setCharm' into a form which |
4269 | + is suitable for the user callback. |
4270 | + |
4271 | + @method handleSetCharm |
4272 | + @param {Function} userCallback The callback originally submitted by the |
4273 | + call site. |
4274 | + @param {String} service_name The name of the service. Passed in since |
4275 | + it is not part of the response. |
4276 | + @param {String} charm_url The URL of the charm. Passed in since |
4277 | + it is not part of the response. |
4278 | + @param {Object} data The response returned by the server. |
4279 | + @return {undefined} Nothing. |
4280 | + */ |
4281 | + handleSetCharm: function(userCallback, service_name, charm_url, data) { |
4282 | + var transformedData = { |
4283 | + err: data.Error, |
4284 | + service_name: service_name, |
4285 | + charm_url: charm_url |
4286 | + }; |
4287 | + // Call the original user callback. |
4288 | + userCallback(transformedData); |
4289 | + }, |
4290 | + |
4291 | + /** |
4292 | * Add units to the provided service. |
4293 | * |
4294 | * @method add_unit |
4295 | |
4296 | === modified file 'app/store/env/sandbox.js' |
4297 | --- app/store/env/sandbox.js 2013-05-17 14:51:05 +0000 |
4298 | +++ app/store/env/sandbox.js 2013-06-26 14:26:26 +0000 |
4299 | @@ -19,7 +19,7 @@ |
4300 | 'use strict'; |
4301 | |
4302 | /** |
4303 | -Sandbox APIs mimicking communications with the Go and Juju backends. |
4304 | +Sandbox APIs mimicking communications with the Go and Python backends. |
4305 | |
4306 | @module env |
4307 | @submodule env.sandbox |
4308 | @@ -682,6 +682,236 @@ |
4309 | }); |
4310 | |
4311 | sandboxModule.PyJujuAPI = PyJujuAPI; |
4312 | + |
4313 | + /** |
4314 | + A sandbox Juju environment using the Go API. |
4315 | + |
4316 | + @class GoJujuAPI |
4317 | + */ |
4318 | + function GoJujuAPI(config) { |
4319 | + GoJujuAPI.superclass.constructor.apply(this, arguments); |
4320 | + } |
4321 | + |
4322 | + GoJujuAPI.NAME = 'sandbox-go-juju-api'; |
4323 | + GoJujuAPI.ATTRS = { |
4324 | + state: {}, |
4325 | + client: {} |
4326 | + }; |
4327 | + |
4328 | + Y.extend(GoJujuAPI, Y.Base, { |
4329 | + |
4330 | + /** |
4331 | + Initializes. |
4332 | + |
4333 | + @method initializer |
4334 | + @return {undefined} Nothing. |
4335 | + */ |
4336 | + initializer: function() { |
4337 | + this.connected = false; |
4338 | + }, |
4339 | + |
4340 | + /** |
4341 | + Opens the connection to the sandbox Juju environment. |
4342 | + Called by ClientConnection, which sends itself. |
4343 | + |
4344 | + @method open |
4345 | + @param {Object} client A ClientConnection. |
4346 | + @return {undefined} Nothing. |
4347 | + */ |
4348 | + open: function(client) { |
4349 | + if (!this.connected) { |
4350 | + this.connected = true; |
4351 | + this.set('client', client); |
4352 | + } else if (this.get('client') !== client) { |
4353 | + throw 'INVALID_STATE_ERR : Connection is open to another client.'; |
4354 | + } |
4355 | + }, |
4356 | + |
4357 | + /** |
4358 | + Closes the connection to the sandbox Juju environment. |
4359 | + Called by ClientConnection. |
4360 | + |
4361 | + @method close |
4362 | + @return {undefined} Nothing. |
4363 | + */ |
4364 | + close: function() { |
4365 | + if (this.connected) { |
4366 | + this.connected = false; |
4367 | + this.set('client', undefined); |
4368 | + } |
4369 | + }, |
4370 | + |
4371 | + /** |
4372 | + Do any extra work to destroy the object. |
4373 | + |
4374 | + @method destructor |
4375 | + @return {undefined} Nothing. |
4376 | + */ |
4377 | + destructor: function() { |
4378 | + this.close(); |
4379 | + }, |
4380 | + |
4381 | + /** |
4382 | + Receives messages from the client and dispatches them. |
4383 | + |
4384 | + @method receive |
4385 | + @param {Object} data A hash of data sent from the client. |
4386 | + @return {undefined} Nothing. |
4387 | + */ |
4388 | + receive: function(data) { |
4389 | + console.log('client message', data); |
4390 | + if (this.connected) { |
4391 | + this['handle' + data.Type + data.Request](data, |
4392 | + this.get('client'), this.get('state')); |
4393 | + } else { |
4394 | + throw CLOSEDERROR; |
4395 | + } |
4396 | + }, |
4397 | + |
4398 | + /** |
4399 | + Handle Login messages to the state object. |
4400 | + |
4401 | + @method handleAdminLogin |
4402 | + @param {Object} data The contents of the API arguments. |
4403 | + @param {Object} client The active ClientConnection. |
4404 | + @param {Object} state An instance of FakeBackend. |
4405 | + @return {undefined} Side effects only. |
4406 | + */ |
4407 | + handleAdminLogin: function(data, client, state) { |
4408 | + data.Error = !state.login(data.Params.AuthTag, data.Params.Password); |
4409 | + client.receive(data); |
4410 | + }, |
4411 | + |
4412 | + /** |
4413 | + Handle EnvironmentView messages. |
4414 | + |
4415 | + @method handleClientServiceGet |
4416 | + @param {Object} data The contents of the API arguments. |
4417 | + @param {Object} client The active ClientConnection. |
4418 | + @param {Object} state An instance of FakeBackend. |
4419 | + @return {undefined} Side effects only. |
4420 | + */ |
4421 | + handleClientEnvironmentInfo: function(data, client, state) { |
4422 | + client.receive({ |
4423 | + ProviderType: state.get('providerType'), |
4424 | + DefaultSeries: state.get('defaultSeries'), |
4425 | + Name: 'Sandbox' |
4426 | + }); |
4427 | + }, |
4428 | + |
4429 | + /** |
4430 | + Handle WatchAll messages. |
4431 | + |
4432 | + @method handleClientWatchAll |
4433 | + @param {Object} data The contents of the API arguments. |
4434 | + @param {Object} client The active ClientConnection. |
4435 | + @param {Object} state An instance of FakeBackend. |
4436 | + @return {undefined} Side effects only. |
4437 | + */ |
4438 | + handleClientWatchAll: function(data, client, state) { |
4439 | + // TODO wire up delta stream to "Next" responses here. |
4440 | + client.receive({Response: {AllWatcherId: '42'}}); |
4441 | + }, |
4442 | + |
4443 | + /** |
4444 | + Handle AllWatcher Next messages. |
4445 | + |
4446 | + @method handleAllWatcherNext |
4447 | + @param {Object} data The contents of the API arguments. |
4448 | + @param {Object} client The active ClientConnection. |
4449 | + @param {Object} state An instance of FakeBackend. |
4450 | + @return {undefined} Side effects only. |
4451 | + */ |
4452 | + handleAllWatcherNext: function(data, client, state) { |
4453 | + // This is a noop for the moment because it must exist but the current |
4454 | + // functionality does not depend on it having any effect. |
4455 | + // TODO See if there are any changes and if so, send them. |
4456 | + }, |
4457 | + |
4458 | + /** |
4459 | + Handle ServiceDeploy messages |
4460 | + |
4461 | + @method handleClientServiceDeploy |
4462 | + @param {Object} data The contents of the API arguments. |
4463 | + @param {Object} client The active ClientConnection. |
4464 | + @param {Object} state An instance of FakeBackend. |
4465 | + @return {undefined} Side effects only. |
4466 | + */ |
4467 | + handleClientServiceDeploy: function(data, client, state) { |
4468 | + var callback = function(result) { |
4469 | + var response = {RequestId: data.RequestId}; |
4470 | + if (result.error) { |
4471 | + response.Error = result.error; |
4472 | + } |
4473 | + client.receive(response); |
4474 | + }; |
4475 | + state.deploy(data.Params.CharmUrl, callback, { |
4476 | + name: data.Params.ServiceName, |
4477 | + config: data.Params.Config, |
4478 | + configYAML: data.Params.ConfigYAML, |
4479 | + unitCount: data.Params.NumUnits |
4480 | + }); |
4481 | + }, |
4482 | + |
4483 | + /** |
4484 | + Handle ServiceSetCharm messages |
4485 | + |
4486 | + @method handleClientServiceSetCharm |
4487 | + @param {Object} data The contents of the API arguments. |
4488 | + @param {Object} client The active ClientConnection. |
4489 | + @param {Object} state An instance of FakeBackend. |
4490 | + @return {undefined} Side effects only. |
4491 | + */ |
4492 | + handleClientServiceSetCharm: function(data, client, state) { |
4493 | + var callback = function(result) { |
4494 | + var response = {RequestId: data.RequestId}; |
4495 | + if (result.error) { |
4496 | + response.Error = result.error; |
4497 | + } |
4498 | + client.receive(response); |
4499 | + }; |
4500 | + state.setCharm(data.Params.ServiceName, data.Params.CharmUrl, |
4501 | + data.Params.Force, callback); |
4502 | + }, |
4503 | + |
4504 | + /** |
4505 | + Handle SetAnnotations messages |
4506 | + |
4507 | + @method handleClientSetAnnotations |
4508 | + @param {Object} data The contents of the API arguments. |
4509 | + @param {Object} client The active ClientConnection. |
4510 | + @param {Object} state An instance of FakeBackend. |
4511 | + @return {undefined} Side effects only. |
4512 | + */ |
4513 | + handleClientSetAnnotations: function(data, client, state) { |
4514 | + var serviceId = /service-([^ ]*)$/.exec(data.Params.Tag)[1]; |
4515 | + var reply = state.updateAnnotations(serviceId, data.Params.Pairs); |
4516 | + client.receive({ |
4517 | + RequestId: data.RequestId, |
4518 | + Error: reply.error}); |
4519 | + }, |
4520 | + |
4521 | + /** |
4522 | + Handle ServiceGet messages |
4523 | + |
4524 | + @method handleClientServiceGet |
4525 | + @param {Object} data The contents of the API arguments. |
4526 | + @param {Object} client The active ClientConnection. |
4527 | + @param {Object} state An instance of FakeBackend. |
4528 | + @return {undefined} Side effects only. |
4529 | + */ |
4530 | + handleClientServiceGet: function(data, client, state) { |
4531 | + var reply = state.getService(data.Params.ServiceName); |
4532 | + // TODO Include the optional Config or Constraints in the response. |
4533 | + client.receive({ |
4534 | + RequestId: data.RequestId, |
4535 | + Error: reply.error, |
4536 | + Response: {Service: data.Params.ServiceName}}); |
4537 | + } |
4538 | + |
4539 | + }); |
4540 | + |
4541 | + sandboxModule.GoJujuAPI = GoJujuAPI; |
4542 | }, '0.1.0', { |
4543 | requires: [ |
4544 | 'base', |
4545 | |
4546 | === modified file 'app/subapps/browser/browser.js' |
4547 | --- app/subapps/browser/browser.js 2013-05-29 18:00:54 +0000 |
4548 | +++ app/subapps/browser/browser.js 2013-06-26 14:26:26 +0000 |
4549 | @@ -34,6 +34,7 @@ |
4550 | |
4551 | @class Browser |
4552 | @extends {juju.SubApp} |
4553 | + |
4554 | */ |
4555 | ns.Browser = Y.Base.create('subapp-browser', Y.juju.SubApp, [], { |
4556 | // Mark the entire subapp has hidden. |
4557 | @@ -41,10 +42,11 @@ |
4558 | viewmodes: ['minimized', 'fullscreen', 'sidebar'], |
4559 | |
4560 | /** |
4561 | - Show or hide the details panel. |
4562 | - |
4563 | - @method _detailsVisible |
4564 | - @param {Boolean} visible set the panel to hide or show. |
4565 | + Show or hide the details panel. |
4566 | + |
4567 | + @method _detailsVisible |
4568 | + @param {Boolean} visible set the panel to hide or show. |
4569 | + |
4570 | */ |
4571 | _detailsVisible: function(visible) { |
4572 | var detailsNode = Y.one('.bws-view-data'); |
4573 | @@ -59,11 +61,12 @@ |
4574 | }, |
4575 | |
4576 | /** |
4577 | - Given the current subapp state, generate a url to pass up to the |
4578 | - routing code to route to. |
4579 | - |
4580 | - @method _getStateUrl |
4581 | - @param {Object} change the values to change in the current state. |
4582 | + Given the current subapp state, generate a url to pass up to the |
4583 | + routing code to route to. |
4584 | + |
4585 | + @method _getStateUrl |
4586 | + @param {Object} change the values to change in the current state. |
4587 | + |
4588 | */ |
4589 | _getStateUrl: function(change) { |
4590 | var urlParts = []; |
4591 | @@ -82,6 +85,9 @@ |
4592 | urlParts.push(this._viewState.viewmode); |
4593 | if (this._viewState.search) { |
4594 | urlParts.push('search'); |
4595 | + } else if (this._oldState.search) { |
4596 | + // We had a search, but are moving away; clear the old search. |
4597 | + this._filter.reset(); |
4598 | } |
4599 | if (this._viewState.charmID) { |
4600 | urlParts.push(this._viewState.charmID); |
4601 | @@ -97,11 +103,12 @@ |
4602 | }, |
4603 | |
4604 | /** |
4605 | - Generate a standard shared set of cfg all Views can expect to see. |
4606 | - |
4607 | - @method _getViewCfg |
4608 | - @param {Object} cfg additional config to merge into the default view |
4609 | - config. |
4610 | + Generate a standard shared set of cfg all Views can expect to see. |
4611 | + |
4612 | + @method _getViewCfg |
4613 | + @param {Object} cfg additional config to merge into the default view |
4614 | + config. |
4615 | + |
4616 | */ |
4617 | _getViewCfg: function(cfg) { |
4618 | // We always add the _filter data to every request because most of them |
4619 | @@ -123,6 +130,7 @@ |
4620 | _initState: function() { |
4621 | this._oldState = { |
4622 | charmID: null, |
4623 | + hash: null, |
4624 | querystring: null, |
4625 | search: null, |
4626 | viewmode: null |
4627 | @@ -149,6 +157,7 @@ |
4628 | Determine if we should render the charm details based on the current |
4629 | state. |
4630 | |
4631 | + @method _shouldShowCharm |
4632 | @return {Boolean} true if should show. |
4633 | */ |
4634 | _shouldShowCharm: function() { |
4635 | @@ -169,23 +178,34 @@ |
4636 | Determine if we should render the editorial content based on the current |
4637 | state. |
4638 | |
4639 | + @method _shouldShowEditorial |
4640 | @return {Boolean} true if should show. |
4641 | */ |
4642 | _shouldShowEditorial: function() { |
4643 | - if ( |
4644 | - !this._viewState.search && |
4645 | + var should = false; |
4646 | + // If the viewmode has changed, and seach is not enabled then yes |
4647 | + if (!this._viewState.search && |
4648 | this._hasStateChanged('viewmode') |
4649 | ) { |
4650 | - return true; |
4651 | - } else { |
4652 | - return false; |
4653 | - } |
4654 | + should = true; |
4655 | + } |
4656 | + |
4657 | + // Even if viewmode hasn't changed, but search has changed and is false |
4658 | + // then yes |
4659 | + if (!this._viewState.search && |
4660 | + this._hasStateChanged('search') |
4661 | + ) { |
4662 | + should = true; |
4663 | + } |
4664 | + |
4665 | + return should; |
4666 | }, |
4667 | |
4668 | /** |
4669 | Determine if we should render the search results based on the current |
4670 | state. |
4671 | |
4672 | + @method _shouldShowSearch |
4673 | @return {Boolean} true if should show. |
4674 | */ |
4675 | _shouldShowSearch: function() { |
4676 | @@ -231,17 +251,23 @@ |
4677 | // Clear out any parts of /sidebar/search, /sidebar, or /search from the |
4678 | // id. See if we still really have an id. |
4679 | var match = |
4680 | - /^(sidebar|fullscreen|minimized|search|test\/index\.html)\/?(search)?/; |
4681 | + /^\/?(sidebar|fullscreen|minimized|search|test\/index\.html)\/?(search)?\/?/; |
4682 | |
4683 | if (id && id.match(match)) { |
4684 | // Strip it out. |
4685 | id = id.replace(match, ''); |
4686 | - |
4687 | // if the id is now empty, set it to null. |
4688 | if (id === '') { |
4689 | id = null; |
4690 | } |
4691 | } |
4692 | + |
4693 | + if (id) { |
4694 | + // Strip any extra slashes off the start/end of the id. |
4695 | + id = id.replace(/^\//, ''); |
4696 | + id = id.replace(/\/$/, ''); |
4697 | + } |
4698 | + |
4699 | return id; |
4700 | }, |
4701 | |
4702 | @@ -260,6 +286,21 @@ |
4703 | }, |
4704 | |
4705 | /** |
4706 | + Does our app instance have a valid store? If not, then we should ignore |
4707 | + a lot of work since we can't do it anyway. Sanity check our |
4708 | + information. During test running, for instance, we don't have a valid |
4709 | + store to work with and that's ok. |
4710 | + |
4711 | + @method _hasValidStore |
4712 | + @return {Boolean} do we have a valid store or not. |
4713 | + |
4714 | + */ |
4715 | + _hasValidStore: function() { |
4716 | + var store = this.get('store'); |
4717 | + return !store.get('noop'); |
4718 | + }, |
4719 | + |
4720 | + /** |
4721 | Update the oldState with the viewState now that we're done processing |
4722 | the request. |
4723 | |
4724 | @@ -282,10 +323,15 @@ |
4725 | // Update the viewmode. Every request has a viewmode. |
4726 | var path = req.path, |
4727 | params = req.params, |
4728 | - query = req.query; |
4729 | + query = req.query, |
4730 | + hash = window.location.hash; |
4731 | |
4732 | this._viewState.viewmode = params.viewmode; |
4733 | |
4734 | + if (hash) { |
4735 | + this._viewState.hash = hash.replace('/', ''); |
4736 | + } |
4737 | + |
4738 | // Check for a charm id in the request. |
4739 | if (params.id && params.id !== 'search') { |
4740 | this._viewState.charmID = params.id; |
4741 | @@ -387,11 +433,20 @@ |
4742 | renderCharmDetails: function(req, res, next) { |
4743 | var charmID = this._viewState.charmID; |
4744 | var extraCfg = { |
4745 | + activeTab: this._viewState.hash, |
4746 | charmID: charmID, |
4747 | container: Y.Node.create('<div class="charmview"/>'), |
4748 | deploy: this.get('deploy') |
4749 | }; |
4750 | |
4751 | + // If the only thing that changed was the hash, then don't redraw. It's |
4752 | + // just someone clicking a tab in the UI. |
4753 | + if (this._details && this._hasStateChanged('hash') && |
4754 | + !(this._hasStateChanged('charmID') || |
4755 | + this._hasStateChanged('viewmode'))) { |
4756 | + return; |
4757 | + } |
4758 | + |
4759 | // The details view needs to know if we're using a fullscreen template |
4760 | // or the sidebar version. |
4761 | if (this._viewState.viewmode === 'fullscreen') { |
4762 | @@ -448,7 +503,6 @@ |
4763 | extraCfg.activeID = this._viewState.charmID; |
4764 | } |
4765 | |
4766 | - |
4767 | this._editorial = new Y.juju.browser.views.EditorialView( |
4768 | this._getViewCfg(extraCfg)); |
4769 | |
4770 | @@ -456,6 +510,16 @@ |
4771 | // Add any sidebar charms to the running cache. |
4772 | this._cache = Y.merge(this._cache, ev.cache); |
4773 | }, this); |
4774 | + this._editorial.on(this._editorial.EV_CATEGORY_LINK_CLICKED, |
4775 | + function(ev) { |
4776 | + var change = { |
4777 | + search: true, |
4778 | + filter: { |
4779 | + categories: [ev.category] |
4780 | + } |
4781 | + }; |
4782 | + this.fire('viewNavigate', {change: change}); |
4783 | + }); |
4784 | |
4785 | this._editorial.render(this._cache.interesting); |
4786 | this._editorial.addTarget(this); |
4787 | @@ -622,9 +686,6 @@ |
4788 | if (this._search) { |
4789 | this._search.set('activeID', null); |
4790 | } |
4791 | - |
4792 | - |
4793 | - |
4794 | } |
4795 | |
4796 | // Sync that the state has changed. |
4797 | @@ -633,6 +694,100 @@ |
4798 | }, |
4799 | |
4800 | /** |
4801 | + When there's no charm or viewmode default to a sidebar view for all |
4802 | + pages. |
4803 | + |
4804 | + @method routeSidebarDefault |
4805 | + @param {Request} req current request object. |
4806 | + @param {Response} res current response object. |
4807 | + @param {function} next callable for the next route in the chain. |
4808 | + |
4809 | + */ |
4810 | + routeSidebarDefault: function(req, res, next) { |
4811 | + // Check if there's any path. If there is, someone else will handle |
4812 | + // routing it. Just carry on. |
4813 | + if (req.path.replace(/\//, '') !== '') { |
4814 | + next(); |
4815 | + return; |
4816 | + } |
4817 | + |
4818 | + // For the * request there will be no req.params. Update it forcing |
4819 | + // sidebar default viewmode. |
4820 | + req.params = { |
4821 | + viewmode: 'sidebar' |
4822 | + }; |
4823 | + |
4824 | + // Update the state for the rest of things to figure out what to do. |
4825 | + this._updateState(req); |
4826 | + |
4827 | + // Once the state is updated determine visibility of our Nodes. |
4828 | + this.updateVisible(); |
4829 | + |
4830 | + // Don't bother routing if we're hidden. |
4831 | + if (!this.hidden) { |
4832 | + this.sidebar(req, res, next); |
4833 | + } else { |
4834 | + // Let the next route go on. |
4835 | + next(); |
4836 | + } |
4837 | + }, |
4838 | + |
4839 | + /** |
4840 | + A url direct to a charm id works, however it needs to default the |
4841 | + viewmode to sidebar in that case. |
4842 | + |
4843 | + Almost any url with a component to it matches this route. We need to |
4844 | + check if there are exactly *two* parts and if so, check if they're a |
4845 | + valid id-able segment. (Not /sidebar/search for instance) |
4846 | + |
4847 | + @method routeDirectCharmId |
4848 | + @param {Request} req current request object. |
4849 | + @param {Response} res current response object. |
4850 | + @param {function} next callable for the next route in the chain. |
4851 | + |
4852 | + */ |
4853 | + routeDirectCharmId: function(req, res, next) { |
4854 | + // If we don't have a valid store we can't do any work here. |
4855 | + if (!this._hasValidStore()) { |
4856 | + return; |
4857 | + } |
4858 | + |
4859 | + // Check if we have exactly two url parts in our path. |
4860 | + // The best way to count the parts is to strip the start/end slash and |
4861 | + // then split on the rest. We only care if there are exactly two parts. |
4862 | + var idBits = req.path.replace(/^\//, '').replace(/\/$/, '').split('/'), |
4863 | + id = null; |
4864 | + |
4865 | + if (idBits.length === 2) { |
4866 | + id = this._stripViewMode(req.path); |
4867 | + } |
4868 | + if (!id) { |
4869 | + next(); |
4870 | + return; |
4871 | + } else { |
4872 | + // We've got a valid id. Setup the params for our view state. |
4873 | + req.params = { |
4874 | + id: id, |
4875 | + viewmode: 'sidebar' |
4876 | + }; |
4877 | + } |
4878 | + |
4879 | + // Update the state for the rest of things to figure out what to do. |
4880 | + this._updateState(req); |
4881 | + |
4882 | + // Once the state is updated determine visibility of our Nodes. |
4883 | + this.updateVisible(); |
4884 | + |
4885 | + // Don't bother routing if we're hidden. |
4886 | + if (!this.hidden) { |
4887 | + this.sidebar(req, res, next); |
4888 | + } else { |
4889 | + // Let the next route go on. |
4890 | + next(); |
4891 | + } |
4892 | + }, |
4893 | + |
4894 | + /** |
4895 | Dispatch to the correct viewmode based on the route that was hit. |
4896 | |
4897 | @method routeView |
4898 | @@ -681,6 +836,8 @@ |
4899 | Based on the viewmode and the hidden check what divs we should be |
4900 | showing or hiding. |
4901 | |
4902 | + @method updateVisible |
4903 | + @return {undefined} Nothing. |
4904 | */ |
4905 | updateVisible: function() { |
4906 | var minview = this.get('minNode'), |
4907 | @@ -723,8 +880,8 @@ |
4908 | |
4909 | /** |
4910 | @attribute store |
4911 | - @default Charmworld1 |
4912 | - @type {Charmworld1} |
4913 | + @default Charmworld2 |
4914 | + @type {Charmworld2} |
4915 | */ |
4916 | store: { |
4917 | /** |
4918 | @@ -733,7 +890,7 @@ |
4919 | tests there's no config for talking to the api so we have to watch |
4920 | out in test runs and allow the store to be broken. |
4921 | |
4922 | - method store.valueFn |
4923 | + @method store.valueFn |
4924 | */ |
4925 | valueFn: function() { |
4926 | var cfg = { |
4927 | @@ -746,7 +903,7 @@ |
4928 | } else { |
4929 | cfg.apiHost = window.juju_config.charmworldURL; |
4930 | } |
4931 | - return new Y.juju.Charmworld1(cfg); |
4932 | + return new Y.juju.Charmworld2(cfg); |
4933 | } |
4934 | }, |
4935 | |
4936 | @@ -759,8 +916,8 @@ |
4937 | value: [ |
4938 | // Show the sidebar on all places if its not manually shut off or |
4939 | // turned into a fullscreen route. |
4940 | - { path: '*', callbacks: 'routeView'}, |
4941 | - { path: '/*id/', callbacks: 'routeView'}, |
4942 | + { path: '*', callbacks: 'routeSidebarDefault'}, |
4943 | + { path: '/*id/', callbacks: 'routeDirectCharmId'}, |
4944 | { path: '/:viewmode/', callbacks: 'routeView' }, |
4945 | { path: '/:viewmode/search/', callbacks: 'routeView' }, |
4946 | { path: '/:viewmode/search/*id/', callbacks: 'routeView' }, |
4947 | @@ -797,6 +954,8 @@ |
4948 | /** |
4949 | Find the minNode and cache it for later use. |
4950 | |
4951 | + @attribute minNode |
4952 | + @readOnly |
4953 | */ |
4954 | valueFn: function() { |
4955 | return Y.one('#subapp-browser-min'); |
4956 | |
4957 | === modified file 'app/subapps/browser/templates/browser_charm.handlebars' |
4958 | --- app/subapps/browser/templates/browser_charm.handlebars 2013-05-29 14:11:48 +0000 |
4959 | +++ app/subapps/browser/templates/browser_charm.handlebars 2013-06-26 14:26:26 +0000 |
4960 | @@ -1,5 +1,5 @@ |
4961 | <div class="charm yui3-g"> |
4962 | - <div class="content yui3-u-{{#if isFullscreen}}5-6{{else}}1{{/if}}"> |
4963 | + <div class="content yui3-u-{{#if isFullscreen}}3-4{{else}}1{{/if}}"> |
4964 | <div class="nav"> |
4965 | <a href="" class="back"> |
4966 | {{#if isFullscreen}} |
4967 | @@ -9,11 +9,16 @@ |
4968 | Close |
4969 | {{/if}} |
4970 | </a> |
4971 | + {{! The add class is used by the deploy method in |
4972 | + test/test_charm_running.py. If you change this name, change |
4973 | + the other one too! }} |
4974 | <a href="" class="add">Add</a> |
4975 | - <a href="" class="share"> |
4976 | - <img src="/juju-ui/assets/images/browser_share_button_icon.png" |
4977 | - alt="Share" />Share |
4978 | - </a> |
4979 | + {{#if shareFlag}} |
4980 | + <a href="" class="share"> |
4981 | + <img src="/juju-ui/assets/images/browser_share_button_icon.png" |
4982 | + alt="Share" />Share |
4983 | + </a> |
4984 | + {{/if}} |
4985 | </div> |
4986 | |
4987 | {{#if failingProviders}} |
4988 | @@ -33,11 +38,17 @@ |
4989 | title="This charm has been reviewed."></span> |
4990 | {{/if}} |
4991 | |
4992 | - {{#if hasIcon}} |
4993 | + {{#if shouldShowIcon}} |
4994 | <img src="{{charmFilePath id 'icon.svg'}}" alt="{{ name }} icon" class="icon"> |
4995 | {{else}} |
4996 | - <div class="charm-icon"> |
4997 | - </div> |
4998 | + {{#if mainCategory}} |
4999 | + <div title="category {{mainCategory}}" |
5000 | + class="category-icon sprite charm-{{mainCategory}}-160"> |
The diff has been truncated for viewing.
Attempt to merge into lp:~juju-gui/juju-gui/juju-gui-test failed due to conflicts:
text conflict in README