sabisu_rails 0.0.1.pre.beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
}
|