Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #731 from rubytoolbox/co-readme-display
README display
- Loading branch information
Showing
14 changed files
with
251 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -61,6 +61,9 @@ gem "http" | |
|
||
gem "sidekiq" | ||
|
||
gem "sanitize" | ||
gem "truncato" | ||
|
||
gem "redcarpet" | ||
gem "slim-rails" | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
.readme | ||
.label | ||
@extend .column, .is-full, .is-2-widescreen | ||
span | ||
@extend .is-size-5 | ||
position: sticky | ||
top: 90px | ||
padding-bottom: 12px | ||
border-bottom: 3px solid $primary | ||
margin-bottom: 24px | ||
|
||
i.fa | ||
@extend .has-text-grey-light | ||
|
||
.content | ||
@extend .column |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,67 @@ | ||
# frozen_string_literal: true | ||
|
||
class Github::Readme < ApplicationRecord | ||
module Scrubber | ||
class << self | ||
# | ||
# Sanitizes given html, drops named anchors and adjusts relative | ||
# links to be based on given base_url (if passed, otherwise that step | ||
# is skipped) | ||
# | ||
def scrub(html, base_url: nil) | ||
return if html.blank? | ||
|
||
sanitized = Sanitize.fragment(html, Sanitize::Config::RELAXED) | ||
|
||
fix_links sanitized, base_url: base_url | ||
end | ||
|
||
private | ||
|
||
def fix_links(sanitized, base_url:) | ||
doc = Nokogiri::HTML.fragment sanitized | ||
|
||
doc.css("a[href]").each do |a| | ||
adjust_link a, base_url: base_url | ||
end | ||
|
||
doc.to_s | ||
end | ||
|
||
def adjust_link(link, base_url:) | ||
href = link["href"] | ||
|
||
# Scrub links to named anchors | ||
if href.start_with?("#") | ||
link.replace link.inner_html | ||
# Relative links get aligned to base_url, depending on whether | ||
# it's an absolute or relative path | ||
elsif base_url && href.exclude?("://") | ||
link["href"] = if href.start_with?("/") | ||
URI.join base_url, href | ||
else | ||
File.join base_url, href | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
self.primary_key = :path | ||
self.table_name = :github_readmes | ||
|
||
belongs_to :github_repo, | ||
primary_key: :path, | ||
foreign_key: :path, | ||
inverse_of: :readme | ||
|
||
def html=(html) | ||
super Scrubber.scrub(html, base_url: github_repo&.blob_url) | ||
end | ||
|
||
def truncated_html(limit: 2000) | ||
return if html.blank? | ||
|
||
Truncato.truncate(html, max_length: limit) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
- if readme | ||
section.readme.section: .container: .columns.is-multiline | ||
.label | ||
span | ||
i.fa.fa-book | ||
strong Project Readme | ||
|
||
.content | ||
= readme.html.html_safe |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
.hero | ||
section.section: .container | ||
p.heading= link_to "Ruby Toolbox UI Components Styleguide", "/pages/components" | ||
h2= current_page.split("/").last.humanize | ||
|
||
- readme = Github::Readme.new(html: "<h1>Hello World!</h1><p>Hello World</p>") | ||
|
||
= component_example "Project README" do | ||
= project_readme readme | ||
|
||
= component_example "Project README is not present" do | ||
= project_readme nil |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# frozen_string_literal: true | ||
|
||
require "rails_helper" | ||
|
||
RSpec.describe "Project Display", type: :feature do | ||
let(:project) do | ||
Factories.project "widgets" | ||
end | ||
|
||
it "can display Project README" do | ||
visit project_path(project) | ||
expect(page).not_to have_selector(".readme") | ||
|
||
project.github_repo.create_readme! html: "<strong>some content</strong>", etag: "1234" | ||
visit project_path(project) | ||
|
||
expect(page).to have_selector(".readme") | ||
|
||
within ".readme" do | ||
expect(page).to have_text("some content") | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# frozen_string_literal: true | ||
|
||
require "rails_helper" | ||
|
||
RSpec.describe Github::Readme, type: :model do | ||
let(:repo) do | ||
GithubRepo.new( | ||
path: "foo/bar", | ||
default_branch: "main" | ||
) | ||
end | ||
|
||
let(:model) do | ||
described_class.new( | ||
html: "<p>Hello World</p>", | ||
etag: "123123", | ||
github_repo: repo | ||
) | ||
end | ||
|
||
describe "html=" do | ||
it "passes the input through the scrubber" do | ||
base_url = "https://example.com/foo" | ||
allow(model.github_repo).to receive(:blob_url).and_return(base_url) | ||
allow(Github::Readme::Scrubber).to receive(:scrub) | ||
.with("input html", base_url: base_url) | ||
.and_return("scrubbed") | ||
|
||
model.html = "input html" | ||
|
||
expect(model.html).to be == "scrubbed" | ||
end | ||
end | ||
|
||
describe "#truncated_html" do | ||
it "is nil when html is empty" do | ||
model.html = " " | ||
expect(model.truncated_html).to be nil | ||
end | ||
|
||
it "returns truncated html" do | ||
model.html = '<a href="https://example.com">Hello</a><p>More</p>' | ||
expect(model.truncated_html(limit: 40)).to be == "<a href='https://example.com'>Hello</a><p>...</p>" | ||
end | ||
end | ||
|
||
describe Github::Readme::Scrubber do | ||
describe ".scrub" do | ||
it "returns nil if html is blank" do | ||
expect(described_class.scrub(" \n ")).to be nil | ||
end | ||
|
||
it "cleans weird html content" do | ||
html = %q{<a href="/" onclick="alert('lol');">Hello</a>} | ||
expect(described_class.scrub(html)).to be == '<a href="/">Hello</a>' | ||
end | ||
|
||
it "removes links to named anchors" do | ||
html = '<p><a href="#foobar">Hello</a></p>' | ||
expect(described_class.scrub(html)).to be == "<p>Hello</p>" | ||
end | ||
|
||
# rubocop:disable RSpec/ExampleLength | ||
it "exchanges relative links with base url when given" do | ||
html = <<~HTML | ||
<p><a href="https://example.com">Unchanged</a></p> | ||
<p><a href="foo/relative">Changed</a></p> | ||
<p><a href="/absolute">Changed too</a></p> | ||
HTML | ||
|
||
expected = <<~HTML | ||
<p><a href="https://example.com">Unchanged</a></p> | ||
<p><a href="https://example.com/subpath/foo/relative">Changed</a></p> | ||
<p><a href="https://example.com/absolute">Changed too</a></p> | ||
HTML | ||
|
||
expect(described_class.scrub(html, base_url: "https://example.com/subpath")).to be == expected | ||
end | ||
# rubocop:enable RSpec/ExampleLength | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters