Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: crystal-lang/crystal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 79e8215eb27f
Choose a base ref
...
head repository: crystal-lang/crystal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: d80757f69e06
Choose a head ref
  • 5 commits
  • 3 files changed
  • 1 contributor

Commits on Sep 16, 2016

  1. static file handler extensibility

    * allow handler inheritors to override the relative path of the file path to lookup given a request path
    Brian J. Cardiff committed Sep 16, 2016
    Copy the full SHA
    6933407 View commit details
  2. [playground] workgroup resources

    * serve files in ./playground/resources/ at http://localhost:8080/workbook/playground/resources/
    * load .css and .js in all workbook pages
    Brian J. Cardiff committed Sep 16, 2016
    Copy the full SHA
    0ac9986 View commit details
  3. [playground] allow querystring when requesting workbook items

    Brian J. Cardiff committed Sep 16, 2016
    Copy the full SHA
    510096c View commit details
  4. [playground] send full html files wihout the playground layout

    Brian J. Cardiff committed Sep 16, 2016
    Copy the full SHA
    43f55c1 View commit details
  5. Merged branch feature/playground-resources into master

    Brian J. Cardiff committed Sep 16, 2016
    Copy the full SHA
    d80757f View commit details
60 changes: 55 additions & 5 deletions src/compiler/crystal/tools/playground/server.cr
Original file line number Diff line number Diff line change
@@ -188,9 +188,23 @@ module Crystal::Playground
end

abstract class PlaygroundPage
@resources = [] of Resource

def render_with_layout(io, &block)
ECR.embed "#{__DIR__}/views/layout.html.ecr", io
end

protected def add_resource(kind, src)
@resources << Resource.new(kind, src)
end

def each_resource(kind)
@resources.each do |res|
yield res if res.kind == kind
end
end

record Resource, kind : Symbol, src : String
end

class FileContentPage < PlaygroundPage
@@ -211,13 +225,19 @@ module Crystal::Playground
end
content
rescue e
e.message
e.message || "Error: generating content for #{@filename}"
end
end

def to_s(io)
render_with_layout(io) do
content
body = content
# avoid the layout if the file is a full html
if File.extname(@filename).starts_with?(".htm") && content.starts_with?("<!")
io << body
else
render_with_layout(io) do
body
end
end
end

@@ -294,18 +314,47 @@ module Crystal::Playground

class WorkbookHandler < HTTP::Handler
def call(context)
case {context.request.method, context.request.resource}
case {context.request.method, context.request.path}
when {"GET", /\/workbook\/playground\/(.*)/}
files = Dir["playground/#{$1}.{md,html,cr}"]
if files.size > 0
context.response.headers["Content-Type"] = "text/html"
context.response << FileContentPage.new(files[0])
page = FileContentPage.new(files[0])
load_resources page
context.response << page
return
end
end

call_next(context)
end

def load_resources(page : PlaygroundPage)
Dir["playground/resources/*.css"].each do |file|
page.add_resource :css, "/workbook/#{file}"
end
Dir["playground/resources/*.js"].each do |file|
page.add_resource :js, "/workbook/#{file}"
end
end
end

class PathStaticFileHandler < HTTP::StaticFileHandler
def initialize(@path : String, public_dir : String, fallthrough = true)
super(public_dir, fallthrough)
end

def call(context)
if context.request.path.try &.starts_with?(@path)
super
else
call_next(context)
end
end

def request_path(path : String) : String
path[@path.size..-1]
end
end

class PathWebSocketHandler < HTTP::WebSocketHandler
@@ -426,6 +475,7 @@ module Crystal::Playground
PageHandler.new("/about", File.join(views_dir, "_about.html")),
PageHandler.new("/settings", File.join(views_dir, "_settings.html")),
PageHandler.new("/workbook", WorkbookIndexPage.new),
PathStaticFileHandler.new("/workbook/playground/resources", "playground/resources", false),
WorkbookHandler.new,
EnvironmentHandler.new(self),
HTTP::StaticFileHandler.new(public_dir),
7 changes: 6 additions & 1 deletion src/compiler/crystal/tools/playground/views/layout.html.ecr
Original file line number Diff line number Diff line change
@@ -7,7 +7,9 @@
<link rel="stylesheet" href="/vendor/CodeMirror-5.12.0/theme/neat.css">
<link rel="stylesheet" href="/vendor/octicons-3.5.0/octicons.css">
<link rel="stylesheet" type="text/css" href="/application.css">

<% each_resource(:css) do |res| %>
<link rel="stylesheet" type="text/css" href="<%= res.src %>">
<% end %>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>

<title>Crystal Playground</title>
@@ -54,5 +56,8 @@
<script type="text/javascript" src="/settings.js"></script>
<script type="text/javascript" src="/session.js"></script>
<script type="text/javascript" src="/application.js"></script>
<% each_resource(:js) do |res| %>
<script type="text/javascript" src="<%= res.src %>"></script>
<% end %>
</body>
</html>
8 changes: 7 additions & 1 deletion src/http/server/handlers/static_file_handler.cr
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ class HTTP::StaticFileHandler < HTTP::Handler

original_path = context.request.path.not_nil!
is_dir_path = original_path.ends_with? "/"
request_path = URI.unescape(original_path)
request_path = self.request_path(URI.unescape(original_path))

# File path cannot contains '\0' (NUL) because all filesystem I know
# don't accept '\0' character as file name.
@@ -67,6 +67,12 @@ class HTTP::StaticFileHandler < HTTP::Handler
end
end

# given a full path of the request, returns the path
# of the file that should be expanded at the public_dir
protected def request_path(path : String) : String
path
end

private def redirect_to(context, url)
context.response.status_code = 302