sabisu_rails 0.0.1.pre.beta
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +109 -0
- data/Rakefile +1 -0
- data/app/assets/javascripts/sabisu_rails/application.js +12 -0
- data/app/assets/javascripts/sabisu_rails/sabisu.js.coffee +40 -0
- data/app/assets/stylesheets/sabisu_rails/application.css.scss +9 -0
- data/app/assets/stylesheets/sabisu_rails/explorer.css.scss +117 -0
- data/app/assets/stylesheets/sabisu_rails/furatto_overrides.scss +24 -0
- data/app/controllers/sabisu_rails/base_controller.rb +16 -0
- data/app/controllers/sabisu_rails/explorer_controller.rb +15 -0
- data/app/helpers/sabisu_rails/explorer_helper.rb +28 -0
- data/app/helpers/sabisu_rails_helper.rb +3 -0
- data/app/views/layouts/sabisu_rails.html.erb +28 -0
- data/app/views/sabisu_rails/explorer/index.html.erb +86 -0
- data/app/views/sabisu_rails/explorer/index.js.erb +6 -0
- data/config/routes.rb +3 -0
- data/lib/generators/sabisu_rails/install_generator.rb +17 -0
- data/lib/generators/sabisu_rails/templates/sabisu_rails.rb +34 -0
- data/lib/sabisu_rails/builders/base.rb +26 -0
- data/lib/sabisu_rails/builders/headers_builder.rb +6 -0
- data/lib/sabisu_rails/builders/url_params_builder.rb +6 -0
- data/lib/sabisu_rails/builders.rb +7 -0
- data/lib/sabisu_rails/engine.rb +5 -0
- data/lib/sabisu_rails/explorer.rb +35 -0
- data/lib/sabisu_rails/helpers/required.rb +14 -0
- data/lib/sabisu_rails/helpers.rb +5 -0
- data/lib/sabisu_rails/railtie.rb +22 -0
- data/lib/sabisu_rails/request.rb +28 -0
- data/lib/sabisu_rails/route_recognizer.rb +34 -0
- data/lib/sabisu_rails/version.rb +3 -0
- data/lib/sabisu_rails.rb +70 -0
- data/sabisu_rails.gemspec +30 -0
- data/vendor/assets/javascripts/sabisu_rails/KelpJSONView.js +120 -0
- data/vendor/assets/javascripts/sabisu_rails/pace.js +2 -0
- data/vendor/assets/stylesheets/sabisu_rails/KelpJSONView.css.scss +50 -0
- data/vendor/assets/stylesheets/sabisu_rails/pace.css +80 -0
- metadata +167 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
module SabisuRails
|
2
|
+
class Explorer
|
3
|
+
|
4
|
+
include SabisuRails::Helpers::Required
|
5
|
+
|
6
|
+
attr_reader :resource, :uri_pattern, :http_method
|
7
|
+
|
8
|
+
def initialize(attrs = {})
|
9
|
+
@resource = attrs[:resource] || SabisuRails.default_resource
|
10
|
+
@uri_pattern = attrs[:uri_pattern]
|
11
|
+
@http_method = attrs[:http_method].nil? ? "get" : attrs[:http_method].downcase
|
12
|
+
end
|
13
|
+
|
14
|
+
# Method to retrieve the resource class name, such as User, Product, etc
|
15
|
+
def resource_class
|
16
|
+
@resource_class ||= @resource.singularize.classify.constantize
|
17
|
+
end
|
18
|
+
|
19
|
+
def resource_name
|
20
|
+
@resource_name ||= @resource.singularize
|
21
|
+
end
|
22
|
+
|
23
|
+
def resource_columns
|
24
|
+
resource_class.columns
|
25
|
+
end
|
26
|
+
|
27
|
+
def resource_attributes
|
28
|
+
resource_columns.map(&:name) - SabisuRails.ignored_attributes
|
29
|
+
end
|
30
|
+
|
31
|
+
def method_missing(meth, *args, &block)
|
32
|
+
resource_class.new.send(meth, *args, &block)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module SabisuRails
|
2
|
+
module Helpers
|
3
|
+
module Required
|
4
|
+
|
5
|
+
def required_attribute?(attr)
|
6
|
+
required_attributes.include? attr.to_sym
|
7
|
+
end
|
8
|
+
|
9
|
+
def required_attributes
|
10
|
+
@required_attributes ||= resource_class.validators.map(&:attributes).flatten.uniq
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rails/railtie'
|
2
|
+
|
3
|
+
module SabisuRails
|
4
|
+
class Railtie < ::Rails::Railtie
|
5
|
+
config.eager_load_namespaces << SabisuRails
|
6
|
+
|
7
|
+
ActiveSupport.on_load :active_record do
|
8
|
+
if SabisuRails.resources.empty?
|
9
|
+
SabisuRails.resources = SabisuRails::RouteRecognizer.new.resources
|
10
|
+
SabisuRails.default_resource = SabisuRails.resources.first.to_s
|
11
|
+
end
|
12
|
+
SabisuRails.app_name = Rails.application.class.parent_name
|
13
|
+
end
|
14
|
+
|
15
|
+
config.after_initialize do
|
16
|
+
unless SabisuRails.configured?
|
17
|
+
warn '[Sabisu] Sabisu is not configured in the application and will use the default values.' +
|
18
|
+
' We recommend you to check the file just created with the installer and setup it up.'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module SabisuRails
|
2
|
+
class Request
|
3
|
+
include HTTParty
|
4
|
+
|
5
|
+
base_uri SabisuRails.base_api_uri
|
6
|
+
headers SabisuRails.api_headers
|
7
|
+
|
8
|
+
def initialize(explorer, body_params, params)
|
9
|
+
@explorer = explorer
|
10
|
+
@body_params = body_params || {}
|
11
|
+
@params = params || {}
|
12
|
+
@headers = SabisuRails::Builders::HeadersBuilder.new(@params[:headers]).build
|
13
|
+
@url_params = SabisuRails::Builders::UrlParamsBuilder.new(@params[:url_params]).build
|
14
|
+
end
|
15
|
+
|
16
|
+
def response
|
17
|
+
self.class.send(@explorer.http_method, "/#{@explorer.resource}/#{@explorer.uri_pattern}", body: resource_body_params, headers: @headers, query: @url_params)
|
18
|
+
end
|
19
|
+
|
20
|
+
def resource_body_params
|
21
|
+
body_params = {}
|
22
|
+
|
23
|
+
body_params[@explorer.resource_name] = @body_params.reject { |k, v| v.blank? }
|
24
|
+
|
25
|
+
body_params
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module SabisuRails
|
2
|
+
class RouteRecognizer
|
3
|
+
attr_reader :paths
|
4
|
+
|
5
|
+
# Based on @bantic solution - https://gist.github.com/bantic/5688232#file-rails_route_recognizer-rb
|
6
|
+
# To use this inside your app, call:
|
7
|
+
# `RouteRecognizer.new.initial_path_segments`
|
8
|
+
# This returns an array, e.g.: ['assets','blog','team','faq','users']
|
9
|
+
|
10
|
+
INITIAL_SEGMENT_REGEX = %r{^\/([^\/\(:]+)}
|
11
|
+
IGNORED_PATHS = ["assets", "rails", "sabisu_rails"]
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
routes = Rails.application.routes.routes
|
15
|
+
@paths = routes.collect {|r| r.path.spec.to_s }
|
16
|
+
end
|
17
|
+
|
18
|
+
def initial_path_segments
|
19
|
+
@initial_path_segments ||= begin
|
20
|
+
paths.collect {|path| match_initial_path_segment(path)}.compact.uniq
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def match_initial_path_segment(path)
|
25
|
+
if match = INITIAL_SEGMENT_REGEX.match(path)
|
26
|
+
match[1]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def resources
|
31
|
+
initial_path_segments - IGNORED_PATHS
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/sabisu_rails.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
|
3
|
+
module SabisuRails
|
4
|
+
extend ActiveSupport::Autoload
|
5
|
+
|
6
|
+
autoload :Request
|
7
|
+
autoload :RouteRecognizer
|
8
|
+
autoload :Explorer
|
9
|
+
autoload :Helpers
|
10
|
+
autoload :Builders
|
11
|
+
|
12
|
+
# We ignore some attribues that might cause a collision between models
|
13
|
+
@@default_ignored_attributes = %w{ created_at updated_at id }
|
14
|
+
|
15
|
+
# We append the extra attributes you want to ignore to the default ones
|
16
|
+
mattr_accessor :ignored_attributes
|
17
|
+
@@ignored_attributes = @@ignored_attributes.to_a + @@default_ignored_attributes
|
18
|
+
|
19
|
+
# Base api uri for the endpoints
|
20
|
+
mattr_accessor :base_api_uri
|
21
|
+
@@base_api_uri = nil
|
22
|
+
|
23
|
+
# HTTP methods for the api
|
24
|
+
@@default_http_methods = %w{ GET POST PUT DELETE PATCH }
|
25
|
+
|
26
|
+
mattr_accessor :http_methods
|
27
|
+
@@http_methods = @@http_methods.to_a + @@default_http_methods
|
28
|
+
|
29
|
+
# Headers to include on each request
|
30
|
+
mattr_accessor :api_headers
|
31
|
+
@@api_headers = {}
|
32
|
+
|
33
|
+
# Layout
|
34
|
+
mattr_accessor :layout
|
35
|
+
@@layout = "sabisu_rails"
|
36
|
+
|
37
|
+
# Resources
|
38
|
+
mattr_accessor :resources
|
39
|
+
@@resources = []
|
40
|
+
|
41
|
+
# Authentication
|
42
|
+
mattr_accessor :authentication_username
|
43
|
+
@@authentication_username = "admin"
|
44
|
+
|
45
|
+
mattr_accessor :authentication_password
|
46
|
+
@@authentication_password = "sekret"
|
47
|
+
|
48
|
+
mattr_accessor :app_name
|
49
|
+
@@app_name = 'Sabisu'
|
50
|
+
|
51
|
+
mattr_accessor :default_resource
|
52
|
+
|
53
|
+
@@configured = false
|
54
|
+
|
55
|
+
def self.configured? #:nodoc:
|
56
|
+
@@configured
|
57
|
+
end
|
58
|
+
|
59
|
+
#Method to configure sabisu
|
60
|
+
def self.setup
|
61
|
+
@@configured = true
|
62
|
+
|
63
|
+
yield self
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
require 'sabisu_rails/railtie'
|
69
|
+
require 'sabisu_rails/engine'
|
70
|
+
require 'sabisu_rails/version'
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sabisu_rails/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "sabisu_rails"
|
8
|
+
spec.version = SabisuRails::VERSION.dup
|
9
|
+
spec.authors = ["Abraham Kuri"]
|
10
|
+
spec.email = ["kurenn@icalialabs.com"]
|
11
|
+
spec.summary = %q{Smart API Explorer}
|
12
|
+
spec.description = %q{A smart api explorer for a rails app}
|
13
|
+
spec.homepage = "https://github.com/IcaliaLabs/sabisu-rails"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split("\n")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.rubyforge_project = "sabisu_rails"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
24
|
+
spec.add_development_dependency "rake", "~> 10.3"
|
25
|
+
spec.add_development_dependency "debugger", "~> 1.6"
|
26
|
+
|
27
|
+
spec.add_dependency "activemodel", '~> 4.0'
|
28
|
+
spec.add_dependency "actionpack", '~> 4.0'
|
29
|
+
spec.add_dependency "httparty", "~> 0.13"
|
30
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
/*
|
2
|
+
* Kelp JSONView – http://kelp.phate.org/2011/11/kelp-json-view-json-syntax-highlighting.html
|
3
|
+
* Modded by Bramus! - http://www.bram.us/
|
4
|
+
*/
|
5
|
+
$.extend(jQuery,
|
6
|
+
{
|
7
|
+
JSONView: function (json, container) {
|
8
|
+
var ob = (typeof json == 'string') ? JSON.parse(json) : json,
|
9
|
+
p,
|
10
|
+
l = [],
|
11
|
+
c = container;
|
12
|
+
|
13
|
+
var repeat = function (s, n) {
|
14
|
+
return new Array(n + 1).join(s);
|
15
|
+
};
|
16
|
+
|
17
|
+
// Check whether a string is an URL – Added by Bramus!
|
18
|
+
var isUrl = function(s) {
|
19
|
+
var regexp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/
|
20
|
+
return regexp.test(s);
|
21
|
+
};
|
22
|
+
|
23
|
+
// Escape string for output – Added by Bramus!
|
24
|
+
var htmlEntities = function(str) {
|
25
|
+
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
26
|
+
}
|
27
|
+
|
28
|
+
//²£¥Í JSON µ²ºc¸ê®Æªº»¼°j¨ç¼Æ
|
29
|
+
//o ¨Ó·½ª«¥ó
|
30
|
+
//isar ¸ê®Æ¬O true ªº¸Ü¥Nªí³o¤@¦¸»¼°j¬°°}¦C¸ê®Æ
|
31
|
+
//s »¼°j¶¥¼h¼Æ
|
32
|
+
var r = function (o, isar, s) {
|
33
|
+
for (var n in o) {
|
34
|
+
var p = o[n];
|
35
|
+
switch (typeof p) {
|
36
|
+
case 'function':
|
37
|
+
break;
|
38
|
+
case 'string':
|
39
|
+
p = isUrl(p) ? '<a href="' + p + '">' + p + '</a>' : htmlEntities(p);
|
40
|
+
if (isar)
|
41
|
+
l.push({ Text: '<span class="jsonstring">"' + p + '"</span><span class="jsontag">,</span>', Step: s });
|
42
|
+
else
|
43
|
+
l.push({ Text: '<span class="jsonname">"' + n + '"</span><span class="jsontag">: </span><span class="jsonstring">"' + p + '"</span><span class="jsontag">,</span>', Step: s });
|
44
|
+
break;
|
45
|
+
case 'boolean':
|
46
|
+
if (isar)
|
47
|
+
l.push({ Text: '<span class="jsonboolean">"' + p + '"</span><span class="jsontag">,</span>', Step: s });
|
48
|
+
else
|
49
|
+
l.push({ Text: '<span class="jsonname">"' + n + '"</span><span class="jsontag">: </span><span class="jsonboolean">' + p + '</span><span class="jsontag">,</span>', Step: s });
|
50
|
+
break;
|
51
|
+
case 'number':
|
52
|
+
if (isar)
|
53
|
+
l.push({ Text: '<span class="jsonnumber">' + p + '</span><span class="jsontag">,</span>', Step: s });
|
54
|
+
else
|
55
|
+
l.push({ Text: '<span class="jsonname">"' + n + '"</span><span class="jsontag">: </span><span class="jsonnumber">' + p + '</span><span class="jsontag">,</span>', Step: s });
|
56
|
+
break;
|
57
|
+
case 'object':
|
58
|
+
if (p === null) {
|
59
|
+
if (isar)
|
60
|
+
l.push({ Text: '<span class="jsonnull">' + p + '</span><span class="jsontag">,</span>', Step: s });
|
61
|
+
else
|
62
|
+
l.push({ Text: '<span class="jsonname">"' + n + '"</span><span class="jsontag">: </span><span class="jsonnull">' + p + '</span><span class="jsontag">,</span>', Step: s });
|
63
|
+
}
|
64
|
+
else if (p.length == undefined) {
|
65
|
+
//object
|
66
|
+
if (!isar) {
|
67
|
+
l.push({ Text: '<span class="jsonname">"' + n + '"</span><span class="jsontag">:</span>', Step: s });
|
68
|
+
}
|
69
|
+
l.push({ Text: '<span class="jsontag">{</span>', Step: s });
|
70
|
+
r(p, false, s + 1);
|
71
|
+
l.push({ Text: '<span class="jsontag">},</span>', Step: s });
|
72
|
+
}
|
73
|
+
else {
|
74
|
+
//array
|
75
|
+
if (!isar) {
|
76
|
+
l.push({ Text: '<span class="jsonname">"' + n + '"</span><span class="jsontag">:</span>', Step: s });
|
77
|
+
}
|
78
|
+
l.push({ Text: '<span class="jsontag">[</span>', Step: s });
|
79
|
+
r(p, true, s + 1);
|
80
|
+
l.push({ Text: '<span class="jsontag">],</span>', Step: s });
|
81
|
+
}
|
82
|
+
break;
|
83
|
+
default: break;
|
84
|
+
}
|
85
|
+
}
|
86
|
+
var last = l.pop();
|
87
|
+
var ct = ',</span>';
|
88
|
+
if (last.Text.substr(last.Text.length - ct.length) == ct)
|
89
|
+
l.push({ Text: last.Text.replace(ct, '</span>'), Step: last.Step });
|
90
|
+
else
|
91
|
+
l.push(last);
|
92
|
+
};
|
93
|
+
|
94
|
+
//±N JavaScript Object ®æ¦¡¤Æ¶ë¶i array ¤¤
|
95
|
+
if (ob.length == undefined) {
|
96
|
+
//object
|
97
|
+
l.push({ Text: '<span class="jsontag">{</span>', Step: 0 });
|
98
|
+
r(ob, false, 1);
|
99
|
+
l.push({ Text: '<span class="jsontag">}</span>', Step: 0 });
|
100
|
+
}
|
101
|
+
else {
|
102
|
+
//array
|
103
|
+
l.push({ Text: '<span class="jsontag">[</span>', Step: 0 });
|
104
|
+
r(ob, true, 1);
|
105
|
+
l.push({ Text: '<span class="jsontag">]</span>', Step: 0 });
|
106
|
+
}
|
107
|
+
|
108
|
+
// Build HTML String
|
109
|
+
var html = '<ol>';
|
110
|
+
for (var index in l) {
|
111
|
+
var jobject = l[index];
|
112
|
+
html += '<li>' + repeat(' ', jobject.Step) + jobject.Text + '</li>';
|
113
|
+
}
|
114
|
+
html += '</ol>';
|
115
|
+
|
116
|
+
// Inject HTML String into container
|
117
|
+
c.addClass('KelpJSONView').html(html);
|
118
|
+
|
119
|
+
}
|
120
|
+
});
|
@@ -0,0 +1,2 @@
|
|
1
|
+
/*! pace 0.5.1 */
|
2
|
+
(function(){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W=[].slice,X={}.hasOwnProperty,Y=function(a,b){function c(){this.constructor=a}for(var d in b)X.call(b,d)&&(a[d]=b[d]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a},Z=[].indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(b in this&&this[b]===a)return b;return-1};for(t={catchupTime:500,initialRate:.03,minTime:500,ghostTime:500,maxProgressPerFrame:10,easeFactor:1.25,startOnPageLoad:!0,restartOnPushState:!0,restartOnRequestAfter:500,target:"body",elements:{checkInterval:100,selectors:["body"]},eventLag:{minSamples:10,sampleCount:3,lagThreshold:3},ajax:{trackMethods:["GET"],trackWebSockets:!0,ignoreURLs:[]}},B=function(){var a;return null!=(a="undefined"!=typeof performance&&null!==performance?"function"==typeof performance.now?performance.now():void 0:void 0)?a:+new Date},D=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame,s=window.cancelAnimationFrame||window.mozCancelAnimationFrame,null==D&&(D=function(a){return setTimeout(a,50)},s=function(a){return clearTimeout(a)}),F=function(a){var b,c;return b=B(),(c=function(){var d;return d=B()-b,d>=33?(b=B(),a(d,function(){return D(c)})):setTimeout(c,33-d)})()},E=function(){var a,b,c;return c=arguments[0],b=arguments[1],a=3<=arguments.length?W.call(arguments,2):[],"function"==typeof c[b]?c[b].apply(c,a):c[b]},u=function(){var a,b,c,d,e,f,g;for(b=arguments[0],d=2<=arguments.length?W.call(arguments,1):[],f=0,g=d.length;g>f;f++)if(c=d[f])for(a in c)X.call(c,a)&&(e=c[a],null!=b[a]&&"object"==typeof b[a]&&null!=e&&"object"==typeof e?u(b[a],e):b[a]=e);return b},p=function(a){var b,c,d,e,f;for(c=b=0,e=0,f=a.length;f>e;e++)d=a[e],c+=Math.abs(d),b++;return c/b},w=function(a,b){var c,d,e;if(null==a&&(a="options"),null==b&&(b=!0),e=document.querySelector("[data-pace-"+a+"]")){if(c=e.getAttribute("data-pace-"+a),!b)return c;try{return JSON.parse(c)}catch(f){return d=f,"undefined"!=typeof console&&null!==console?console.error("Error parsing inline pace options",d):void 0}}},g=function(){function a(){}return a.prototype.on=function(a,b,c,d){var e;return null==d&&(d=!1),null==this.bindings&&(this.bindings={}),null==(e=this.bindings)[a]&&(e[a]=[]),this.bindings[a].push({handler:b,ctx:c,once:d})},a.prototype.once=function(a,b,c){return this.on(a,b,c,!0)},a.prototype.off=function(a,b){var c,d,e;if(null!=(null!=(d=this.bindings)?d[a]:void 0)){if(null==b)return delete this.bindings[a];for(c=0,e=[];c<this.bindings[a].length;)this.bindings[a][c].handler===b?e.push(this.bindings[a].splice(c,1)):e.push(c++);return e}},a.prototype.trigger=function(){var a,b,c,d,e,f,g,h,i;if(c=arguments[0],a=2<=arguments.length?W.call(arguments,1):[],null!=(g=this.bindings)?g[c]:void 0){for(e=0,i=[];e<this.bindings[c].length;)h=this.bindings[c][e],d=h.handler,b=h.ctx,f=h.once,d.apply(null!=b?b:this,a),f?i.push(this.bindings[c].splice(e,1)):i.push(e++);return i}},a}(),null==window.Pace&&(window.Pace={}),u(Pace,g.prototype),C=Pace.options=u({},t,window.paceOptions,w()),T=["ajax","document","eventLag","elements"],P=0,R=T.length;R>P;P++)J=T[P],C[J]===!0&&(C[J]=t[J]);i=function(a){function b(){return U=b.__super__.constructor.apply(this,arguments)}return Y(b,a),b}(Error),b=function(){function a(){this.progress=0}return a.prototype.getElement=function(){var a;if(null==this.el){if(a=document.querySelector(C.target),!a)throw new i;this.el=document.createElement("div"),this.el.className="pace pace-active",document.body.className=document.body.className.replace(/pace-done/g,""),document.body.className+=" pace-running",this.el.innerHTML='<div class="pace-progress">\n <div class="pace-progress-inner"></div>\n</div>\n<div class="pace-activity"></div>',null!=a.firstChild?a.insertBefore(this.el,a.firstChild):a.appendChild(this.el)}return this.el},a.prototype.finish=function(){var a;return a=this.getElement(),a.className=a.className.replace("pace-active",""),a.className+=" pace-inactive",document.body.className=document.body.className.replace("pace-running",""),document.body.className+=" pace-done"},a.prototype.update=function(a){return this.progress=a,this.render()},a.prototype.destroy=function(){try{this.getElement().parentNode.removeChild(this.getElement())}catch(a){i=a}return this.el=void 0},a.prototype.render=function(){var a,b;return null==document.querySelector(C.target)?!1:(a=this.getElement(),a.children[0].style.width=""+this.progress+"%",(!this.lastRenderedProgress||this.lastRenderedProgress|0!==this.progress|0)&&(a.children[0].setAttribute("data-progress-text",""+(0|this.progress)+"%"),this.progress>=100?b="99":(b=this.progress<10?"0":"",b+=0|this.progress),a.children[0].setAttribute("data-progress",""+b)),this.lastRenderedProgress=this.progress)},a.prototype.done=function(){return this.progress>=100},a}(),h=function(){function a(){this.bindings={}}return a.prototype.trigger=function(a,b){var c,d,e,f,g;if(null!=this.bindings[a]){for(f=this.bindings[a],g=[],d=0,e=f.length;e>d;d++)c=f[d],g.push(c.call(this,b));return g}},a.prototype.on=function(a,b){var c;return null==(c=this.bindings)[a]&&(c[a]=[]),this.bindings[a].push(b)},a}(),O=window.XMLHttpRequest,N=window.XDomainRequest,M=window.WebSocket,v=function(a,b){var c,d,e,f;f=[];for(d in b.prototype)try{e=b.prototype[d],null==a[d]&&"function"!=typeof e?f.push(a[d]=e):f.push(void 0)}catch(g){c=g}return f},z=[],Pace.ignore=function(){var a,b,c;return b=arguments[0],a=2<=arguments.length?W.call(arguments,1):[],z.unshift("ignore"),c=b.apply(null,a),z.shift(),c},Pace.track=function(){var a,b,c;return b=arguments[0],a=2<=arguments.length?W.call(arguments,1):[],z.unshift("track"),c=b.apply(null,a),z.shift(),c},I=function(a){var b;if(null==a&&(a="GET"),"track"===z[0])return"force";if(!z.length&&C.ajax){if("socket"===a&&C.ajax.trackWebSockets)return!0;if(b=a.toUpperCase(),Z.call(C.ajax.trackMethods,b)>=0)return!0}return!1},j=function(a){function b(){var a,c=this;b.__super__.constructor.apply(this,arguments),a=function(a){var b;return b=a.open,a.open=function(d,e){return I(d)&&c.trigger("request",{type:d,url:e,request:a}),b.apply(a,arguments)}},window.XMLHttpRequest=function(b){var c;return c=new O(b),a(c),c},v(window.XMLHttpRequest,O),null!=N&&(window.XDomainRequest=function(){var b;return b=new N,a(b),b},v(window.XDomainRequest,N)),null!=M&&C.ajax.trackWebSockets&&(window.WebSocket=function(a,b){var d;return d=null!=b?new M(a,b):new M(a),I("socket")&&c.trigger("request",{type:"socket",url:a,protocols:b,request:d}),d},v(window.WebSocket,M))}return Y(b,a),b}(h),Q=null,x=function(){return null==Q&&(Q=new j),Q},H=function(a){var b,c,d,e;for(e=C.ajax.ignoreURLs,c=0,d=e.length;d>c;c++)if(b=e[c],"string"==typeof b){if(-1!==a.indexOf(b))return!0}else if(b.test(a))return!0;return!1},x().on("request",function(b){var c,d,e,f,g;return f=b.type,e=b.request,g=b.url,H(g)?void 0:Pace.running||C.restartOnRequestAfter===!1&&"force"!==I(f)?void 0:(d=arguments,c=C.restartOnRequestAfter||0,"boolean"==typeof c&&(c=0),setTimeout(function(){var b,c,g,h,i,j;if(b="socket"===f?e.readyState<2:0<(h=e.readyState)&&4>h){for(Pace.restart(),i=Pace.sources,j=[],c=0,g=i.length;g>c;c++){if(J=i[c],J instanceof a){J.watch.apply(J,d);break}j.push(void 0)}return j}},c))}),a=function(){function a(){var a=this;this.elements=[],x().on("request",function(){return a.watch.apply(a,arguments)})}return a.prototype.watch=function(a){var b,c,d,e;return d=a.type,b=a.request,e=a.url,H(e)?void 0:(c="socket"===d?new m(b):new n(b),this.elements.push(c))},a}(),n=function(){function a(a){var b,c,d,e,f,g,h=this;if(this.progress=0,null!=window.ProgressEvent)for(c=null,a.addEventListener("progress",function(a){return h.progress=a.lengthComputable?100*a.loaded/a.total:h.progress+(100-h.progress)/2}),g=["load","abort","timeout","error"],d=0,e=g.length;e>d;d++)b=g[d],a.addEventListener(b,function(){return h.progress=100});else f=a.onreadystatechange,a.onreadystatechange=function(){var b;return 0===(b=a.readyState)||4===b?h.progress=100:3===a.readyState&&(h.progress=50),"function"==typeof f?f.apply(null,arguments):void 0}}return a}(),m=function(){function a(a){var b,c,d,e,f=this;for(this.progress=0,e=["error","open"],c=0,d=e.length;d>c;c++)b=e[c],a.addEventListener(b,function(){return f.progress=100})}return a}(),d=function(){function a(a){var b,c,d,f;for(null==a&&(a={}),this.elements=[],null==a.selectors&&(a.selectors=[]),f=a.selectors,c=0,d=f.length;d>c;c++)b=f[c],this.elements.push(new e(b))}return a}(),e=function(){function a(a){this.selector=a,this.progress=0,this.check()}return a.prototype.check=function(){var a=this;return document.querySelector(this.selector)?this.done():setTimeout(function(){return a.check()},C.elements.checkInterval)},a.prototype.done=function(){return this.progress=100},a}(),c=function(){function a(){var a,b,c=this;this.progress=null!=(b=this.states[document.readyState])?b:100,a=document.onreadystatechange,document.onreadystatechange=function(){return null!=c.states[document.readyState]&&(c.progress=c.states[document.readyState]),"function"==typeof a?a.apply(null,arguments):void 0}}return a.prototype.states={loading:0,interactive:50,complete:100},a}(),f=function(){function a(){var a,b,c,d,e,f=this;this.progress=0,a=0,e=[],d=0,c=B(),b=setInterval(function(){var g;return g=B()-c-50,c=B(),e.push(g),e.length>C.eventLag.sampleCount&&e.shift(),a=p(e),++d>=C.eventLag.minSamples&&a<C.eventLag.lagThreshold?(f.progress=100,clearInterval(b)):f.progress=100*(3/(a+3))},50)}return a}(),l=function(){function a(a){this.source=a,this.last=this.sinceLastUpdate=0,this.rate=C.initialRate,this.catchup=0,this.progress=this.lastProgress=0,null!=this.source&&(this.progress=E(this.source,"progress"))}return a.prototype.tick=function(a,b){var c;return null==b&&(b=E(this.source,"progress")),b>=100&&(this.done=!0),b===this.last?this.sinceLastUpdate+=a:(this.sinceLastUpdate&&(this.rate=(b-this.last)/this.sinceLastUpdate),this.catchup=(b-this.progress)/C.catchupTime,this.sinceLastUpdate=0,this.last=b),b>this.progress&&(this.progress+=this.catchup*a),c=1-Math.pow(this.progress/100,C.easeFactor),this.progress+=c*this.rate*a,this.progress=Math.min(this.lastProgress+C.maxProgressPerFrame,this.progress),this.progress=Math.max(0,this.progress),this.progress=Math.min(100,this.progress),this.lastProgress=this.progress,this.progress},a}(),K=null,G=null,q=null,L=null,o=null,r=null,Pace.running=!1,y=function(){return C.restartOnPushState?Pace.restart():void 0},null!=window.history.pushState&&(S=window.history.pushState,window.history.pushState=function(){return y(),S.apply(window.history,arguments)}),null!=window.history.replaceState&&(V=window.history.replaceState,window.history.replaceState=function(){return y(),V.apply(window.history,arguments)}),k={ajax:a,elements:d,document:c,eventLag:f},(A=function(){var a,c,d,e,f,g,h,i;for(Pace.sources=K=[],g=["ajax","elements","document","eventLag"],c=0,e=g.length;e>c;c++)a=g[c],C[a]!==!1&&K.push(new k[a](C[a]));for(i=null!=(h=C.extraSources)?h:[],d=0,f=i.length;f>d;d++)J=i[d],K.push(new J(C));return Pace.bar=q=new b,G=[],L=new l})(),Pace.stop=function(){return Pace.trigger("stop"),Pace.running=!1,q.destroy(),r=!0,null!=o&&("function"==typeof s&&s(o),o=null),A()},Pace.restart=function(){return Pace.trigger("restart"),Pace.stop(),Pace.start()},Pace.go=function(){var a;return Pace.running=!0,q.render(),a=B(),r=!1,o=F(function(b,c){var d,e,f,g,h,i,j,k,m,n,o,p,s,t,u,v;for(k=100-q.progress,e=o=0,f=!0,i=p=0,t=K.length;t>p;i=++p)for(J=K[i],n=null!=G[i]?G[i]:G[i]=[],h=null!=(v=J.elements)?v:[J],j=s=0,u=h.length;u>s;j=++s)g=h[j],m=null!=n[j]?n[j]:n[j]=new l(g),f&=m.done,m.done||(e++,o+=m.tick(b));return d=o/e,q.update(L.tick(b,d)),q.done()||f||r?(q.update(100),Pace.trigger("done"),setTimeout(function(){return q.finish(),Pace.running=!1,Pace.trigger("hide")},Math.max(C.ghostTime,Math.max(C.minTime-(B()-a),0)))):c()})},Pace.start=function(a){u(C,a),Pace.running=!0;try{q.render()}catch(b){i=b}return document.querySelector(".pace")?(Pace.trigger("start"),Pace.go()):setTimeout(Pace.start,50)},"function"==typeof define&&define.amd?define(function(){return Pace}):"object"==typeof exports?module.exports=Pace:C.startOnPageLoad&&Pace.start()}).call(this);
|
@@ -0,0 +1,50 @@
|
|
1
|
+
.KelpJSONView
|
2
|
+
{
|
3
|
+
font-family: monospace;
|
4
|
+
font-weight: 400;
|
5
|
+
font-style:normal;
|
6
|
+
font-size:14px;
|
7
|
+
background-color: #3F3F3F;
|
8
|
+
padding: 6px;
|
9
|
+
}
|
10
|
+
.KelpJSONView ol {
|
11
|
+
background: transparent;
|
12
|
+
margin: 0;
|
13
|
+
padding: 0;
|
14
|
+
color: gainsboro;
|
15
|
+
list-style-position: inside;
|
16
|
+
list-style: none;
|
17
|
+
}
|
18
|
+
.KelpJSONView ol li
|
19
|
+
{
|
20
|
+
white-space:nowrap;
|
21
|
+
margin-bottom: 0;
|
22
|
+
}
|
23
|
+
.jsonname
|
24
|
+
{
|
25
|
+
color: #ddddbe;
|
26
|
+
}
|
27
|
+
.jsonstring
|
28
|
+
{
|
29
|
+
color: #CC9393;
|
30
|
+
}
|
31
|
+
|
32
|
+
.jsonstring a {
|
33
|
+
color: #c79696;
|
34
|
+
}
|
35
|
+
.jsonnull
|
36
|
+
{
|
37
|
+
color: #FFF;
|
38
|
+
}
|
39
|
+
.jsonnumber
|
40
|
+
{
|
41
|
+
color: #8CD0D3;
|
42
|
+
}
|
43
|
+
.jsonboolean
|
44
|
+
{
|
45
|
+
color: #b64B72;
|
46
|
+
}
|
47
|
+
.jsontag
|
48
|
+
{
|
49
|
+
color: gainsboro;
|
50
|
+
}
|
@@ -0,0 +1,80 @@
|
|
1
|
+
.pace {
|
2
|
+
-webkit-pointer-events: none;
|
3
|
+
pointer-events: none;
|
4
|
+
-webkit-user-select: none;
|
5
|
+
-moz-user-select: none;
|
6
|
+
user-select: none;
|
7
|
+
}
|
8
|
+
|
9
|
+
.pace-inactive {
|
10
|
+
display: none;
|
11
|
+
}
|
12
|
+
|
13
|
+
.pace .pace-progress {
|
14
|
+
background: #ea5d5f;
|
15
|
+
position: fixed;
|
16
|
+
z-index: 2000;
|
17
|
+
top: 0;
|
18
|
+
left: 0;
|
19
|
+
height: 2px;
|
20
|
+
|
21
|
+
-webkit-transition: width 1s;
|
22
|
+
-moz-transition: width 1s;
|
23
|
+
-o-transition: width 1s;
|
24
|
+
transition: width 1s;
|
25
|
+
}
|
26
|
+
|
27
|
+
.pace .pace-progress-inner {
|
28
|
+
display: block;
|
29
|
+
position: absolute;
|
30
|
+
right: 0px;
|
31
|
+
width: 100px;
|
32
|
+
height: 100%;
|
33
|
+
box-shadow: 0 0 10px #ea5d5f, 0 0 5px #ea5d5f;
|
34
|
+
opacity: 1.0;
|
35
|
+
-webkit-transform: rotate(3deg) translate(0px, -4px);
|
36
|
+
-moz-transform: rotate(3deg) translate(0px, -4px);
|
37
|
+
-ms-transform: rotate(3deg) translate(0px, -4px);
|
38
|
+
-o-transform: rotate(3deg) translate(0px, -4px);
|
39
|
+
transform: rotate(3deg) translate(0px, -4px);
|
40
|
+
}
|
41
|
+
|
42
|
+
.pace .pace-activity {
|
43
|
+
display: block;
|
44
|
+
position: fixed;
|
45
|
+
z-index: 2000;
|
46
|
+
top: 15px;
|
47
|
+
right: 15px;
|
48
|
+
width: 14px;
|
49
|
+
height: 14px;
|
50
|
+
border: solid 2px transparent;
|
51
|
+
border-top-color: #ea5d5f;
|
52
|
+
border-left-color: #ea5d5f;
|
53
|
+
border-radius: 10px;
|
54
|
+
-webkit-animation: pace-spinner 400ms linear infinite;
|
55
|
+
-moz-animation: pace-spinner 400ms linear infinite;
|
56
|
+
-ms-animation: pace-spinner 400ms linear infinite;
|
57
|
+
-o-animation: pace-spinner 400ms linear infinite;
|
58
|
+
animation: pace-spinner 400ms linear infinite;
|
59
|
+
}
|
60
|
+
|
61
|
+
@-webkit-keyframes pace-spinner {
|
62
|
+
0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); }
|
63
|
+
100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); }
|
64
|
+
}
|
65
|
+
@-moz-keyframes pace-spinner {
|
66
|
+
0% { -moz-transform: rotate(0deg); transform: rotate(0deg); }
|
67
|
+
100% { -moz-transform: rotate(360deg); transform: rotate(360deg); }
|
68
|
+
}
|
69
|
+
@-o-keyframes pace-spinner {
|
70
|
+
0% { -o-transform: rotate(0deg); transform: rotate(0deg); }
|
71
|
+
100% { -o-transform: rotate(360deg); transform: rotate(360deg); }
|
72
|
+
}
|
73
|
+
@-ms-keyframes pace-spinner {
|
74
|
+
0% { -ms-transform: rotate(0deg); transform: rotate(0deg); }
|
75
|
+
100% { -ms-transform: rotate(360deg); transform: rotate(360deg); }
|
76
|
+
}
|
77
|
+
@keyframes pace-spinner {
|
78
|
+
0% { transform: rotate(0deg); transform: rotate(0deg); }
|
79
|
+
100% { transform: rotate(360deg); transform: rotate(360deg); }
|
80
|
+
}
|