Commit ff84cc0b authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'master' into 18533-graphs-wiki-subnav

Signed-off-by: default avatarDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
parents 76c6b9c8 15516150
...@@ -16,6 +16,7 @@ v 8.9.0 (unreleased) ...@@ -16,6 +16,7 @@ v 8.9.0 (unreleased)
- Fix issue with arrow keys not working in search autocomplete dropdown - Fix issue with arrow keys not working in search autocomplete dropdown
- Fix an issue where note polling stopped working if a window was in the - Fix an issue where note polling stopped working if a window was in the
background during a refresh. background during a refresh.
- Pre-processing Markdown now only happens when needed
- Make EmailsOnPushWorker use Sidekiq mailers queue - Make EmailsOnPushWorker use Sidekiq mailers queue
- Redesign all Devise emails. !4297 - Redesign all Devise emails. !4297
- Don't show 'Leave Project' to group members - Don't show 'Leave Project' to group members
......
...@@ -48,7 +48,7 @@ gem 'attr_encrypted', '~> 3.0.0' ...@@ -48,7 +48,7 @@ gem 'attr_encrypted', '~> 3.0.0'
gem 'u2f', '~> 0.2.1' gem 'u2f', '~> 0.2.1'
# Browser detection # Browser detection
gem "browser", '~> 2.0.3' gem "browser", '~> 2.2'
# Extracting information from a git repository # Extracting information from a git repository
# Provide access to Gitlab::Git library # Provide access to Gitlab::Git library
......
...@@ -98,7 +98,7 @@ GEM ...@@ -98,7 +98,7 @@ GEM
autoprefixer-rails (>= 5.2.1) autoprefixer-rails (>= 5.2.1)
sass (>= 3.3.4) sass (>= 3.3.4)
brakeman (3.3.2) brakeman (3.3.2)
browser (2.0.3) browser (2.2.0)
builder (3.2.2) builder (3.2.2)
bullet (5.0.0) bullet (5.0.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
...@@ -833,7 +833,7 @@ DEPENDENCIES ...@@ -833,7 +833,7 @@ DEPENDENCIES
binding_of_caller (~> 0.7.2) binding_of_caller (~> 0.7.2)
bootstrap-sass (~> 3.3.0) bootstrap-sass (~> 3.3.0)
brakeman (~> 3.3.0) brakeman (~> 3.3.0)
browser (~> 2.0.3) browser (~> 2.2)
bullet bullet
bundler-audit bundler-audit
byebug byebug
......
...@@ -121,6 +121,11 @@ window.onload = -> ...@@ -121,6 +121,11 @@ window.onload = ->
setTimeout shiftWindow, 100 setTimeout shiftWindow, 100
$ -> $ ->
$document = $(document)
$window = $(window)
$body = $('body')
gl.utils.preventDisabledButtons() gl.utils.preventDisabledButtons()
bootstrapBreakpoint = bp.getBreakpointSize() bootstrapBreakpoint = bp.getBreakpointSize()
...@@ -152,7 +157,7 @@ $ -> ...@@ -152,7 +157,7 @@ $ ->
), 1 ), 1
# Initialize tooltips # Initialize tooltips
$('body').tooltip( $body.tooltip(
selector: '.has-tooltip, [data-toggle="tooltip"]' selector: '.has-tooltip, [data-toggle="tooltip"]'
placement: (_, el) -> placement: (_, el) ->
$el = $(el) $el = $(el)
...@@ -171,7 +176,7 @@ $ -> ...@@ -171,7 +176,7 @@ $ ->
flash.show() flash.show()
# Disable form buttons while a form is submitting # Disable form buttons while a form is submitting
$('body').on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) -> $body.on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) ->
buttons = $('[type="submit"]', @) buttons = $('[type="submit"]', @)
switch e.type switch e.type
...@@ -184,7 +189,7 @@ $ -> ...@@ -184,7 +189,7 @@ $ ->
$('.account-box').hover -> $(@).toggleClass('hover') $('.account-box').hover -> $(@).toggleClass('hover')
# Commit show suppressed diff # Commit show suppressed diff
$(document).on 'click', '.diff-content .js-show-suppressed-diff', -> $document.on 'click', '.diff-content .js-show-suppressed-diff', ->
$container = $(@).parent() $container = $(@).parent()
$container.next('table').show() $container.next('table').show()
$container.remove() $container.remove()
...@@ -197,13 +202,13 @@ $ -> ...@@ -197,13 +202,13 @@ $ ->
$('.navbar-toggle i').toggleClass("fa-angle-right fa-angle-left") $('.navbar-toggle i').toggleClass("fa-angle-right fa-angle-left")
# Show/hide comments on diff # Show/hide comments on diff
$("body").on "click", ".js-toggle-diff-comments", (e) -> $body.on "click", ".js-toggle-diff-comments", (e) ->
$(@).toggleClass('active') $(@).toggleClass('active')
$(@).closest(".diff-file").find(".notes_holder").toggle() $(@).closest(".diff-file").find(".notes_holder").toggle()
e.preventDefault() e.preventDefault()
$(document).off "click", '.js-confirm-danger' $document.off "click", '.js-confirm-danger'
$(document).on "click", '.js-confirm-danger', (e) -> $document.on "click", '.js-confirm-danger', (e) ->
e.preventDefault() e.preventDefault()
btn = $(e.target) btn = $(e.target)
text = btn.data("confirm-danger-message") text = btn.data("confirm-danger-message")
...@@ -211,7 +216,7 @@ $ -> ...@@ -211,7 +216,7 @@ $ ->
new ConfirmDangerModal(form, text) new ConfirmDangerModal(form, text)
$(document).on 'click', 'button', -> $document.on 'click', 'button', ->
$(this).blur() $(this).blur()
$('input[type="search"]').each -> $('input[type="search"]').each ->
...@@ -219,7 +224,7 @@ $ -> ...@@ -219,7 +224,7 @@ $ ->
$this.attr 'value', $this.val() $this.attr 'value', $this.val()
return return
$(document) $document
.off 'keyup', 'input[type="search"]' .off 'keyup', 'input[type="search"]'
.on 'keyup', 'input[type="search"]' , (e) -> .on 'keyup', 'input[type="search"]' , (e) ->
$this = $(this) $this = $(this)
...@@ -227,7 +232,7 @@ $ -> ...@@ -227,7 +232,7 @@ $ ->
$sidebarGutterToggle = $('.js-sidebar-toggle') $sidebarGutterToggle = $('.js-sidebar-toggle')
$(document) $document
.off 'breakpoint:change' .off 'breakpoint:change'
.on 'breakpoint:change', (e, breakpoint) -> .on 'breakpoint:change', (e, breakpoint) ->
if breakpoint is 'sm' or breakpoint is 'xs' if breakpoint is 'sm' or breakpoint is 'xs'
...@@ -239,14 +244,14 @@ $ -> ...@@ -239,14 +244,14 @@ $ ->
oldBootstrapBreakpoint = bootstrapBreakpoint oldBootstrapBreakpoint = bootstrapBreakpoint
bootstrapBreakpoint = bp.getBreakpointSize() bootstrapBreakpoint = bp.getBreakpointSize()
if bootstrapBreakpoint != oldBootstrapBreakpoint if bootstrapBreakpoint != oldBootstrapBreakpoint
$(document).trigger('breakpoint:change', [bootstrapBreakpoint]) $document.trigger('breakpoint:change', [bootstrapBreakpoint])
checkInitialSidebarSize = -> checkInitialSidebarSize = ->
bootstrapBreakpoint = bp.getBreakpointSize() bootstrapBreakpoint = bp.getBreakpointSize()
if bootstrapBreakpoint is "xs" or "sm" if bootstrapBreakpoint is "xs" or "sm"
$(document).trigger('breakpoint:change', [bootstrapBreakpoint]) $document.trigger('breakpoint:change', [bootstrapBreakpoint])
$(window) $window
.off "resize.app" .off "resize.app"
.on "resize.app", (e) -> .on "resize.app", (e) ->
fitSidebarForSize() fitSidebarForSize()
...@@ -256,14 +261,14 @@ $ -> ...@@ -256,14 +261,14 @@ $ ->
new Aside() new Aside()
# Sidenav pinning # Sidenav pinning
if $(window).width() < 1440 and $.cookie('pin_nav') is 'true' if $window.width() < 1440 and $.cookie('pin_nav') is 'true'
$.cookie('pin_nav', 'false', { path: '/' }) $.cookie('pin_nav', 'false', { path: '/' })
$('.page-with-sidebar') $('.page-with-sidebar')
.toggleClass('page-sidebar-collapsed page-sidebar-expanded') .toggleClass('page-sidebar-collapsed page-sidebar-expanded')
.removeClass('page-sidebar-pinned') .removeClass('page-sidebar-pinned')
$('.navbar-fixed-top').removeClass('header-pinned-nav') $('.navbar-fixed-top').removeClass('header-pinned-nav')
$(document) $document
.off 'click', '.js-nav-pin' .off 'click', '.js-nav-pin'
.on 'click', '.js-nav-pin', (e) -> .on 'click', '.js-nav-pin', (e) ->
e.preventDefault() e.preventDefault()
......
...@@ -121,7 +121,11 @@ class @ContributorsMasterGraph extends ContributorsGraph ...@@ -121,7 +121,11 @@ class @ContributorsMasterGraph extends ContributorsGraph
class @ContributorsAuthorGraph extends ContributorsGraph class @ContributorsAuthorGraph extends ContributorsGraph
constructor: (@data) -> constructor: (@data) ->
@width = $('.content').width()/2 - 100 # Don't split graph size in half for mobile devices.
if $(window).width() < 768
@width = $('.content').width() - 80
else
@width = ($('.content').width() / 2) - 100
@height = 200 @height = 200
@x = null @x = null
@y = null @y = null
......
...@@ -106,6 +106,11 @@ ...@@ -106,6 +106,11 @@
.oneline { .oneline {
line-height: 35px; line-height: 35px;
} }
&.no-bottom-space {
border-bottom: 0;
margin-bottom: 0;
}
} }
.cover-block { .cover-block {
......
...@@ -461,10 +461,12 @@ ...@@ -461,10 +461,12 @@
} }
} }
.ui-state-active, .ui-datepicker-calendar {
.ui-state-hover { .ui-state-hover,
color: $md-link-color; .ui-state-active {
background-color: $calendar-hover-bg; color: #fff;
border: 0;
}
} }
.ui-datepicker-prev, .ui-datepicker-prev,
......
...@@ -91,7 +91,6 @@ ...@@ -91,7 +91,6 @@
text-decoration: none; text-decoration: none;
font-weight: normal; font-weight: normal;
outline: none; outline: none;
white-space: nowrap;
&:hover, &:hover,
&:active, &:active,
......
...@@ -50,11 +50,10 @@ ...@@ -50,11 +50,10 @@
.label-row { .label-row {
.label-name { .label-name {
display: block; display: inline-block;
margin-bottom: 10px; margin-bottom: 10px;
@media (min-width: $screen-sm-min) { @media (min-width: $screen-sm-min) {
display: inline-block;
width: 200px; width: 200px;
margin-bottom: 0; margin-bottom: 0;
} }
...@@ -63,6 +62,7 @@ ...@@ -63,6 +62,7 @@
.label-description { .label-description {
display: block; display: block;
margin-bottom: 10px; margin-bottom: 10px;
margin-left: 50px;
@media (min-width: $screen-sm-min) { @media (min-width: $screen-sm-min) {
display: inline-block; display: inline-block;
......
...@@ -36,11 +36,16 @@ ...@@ -36,11 +36,16 @@
.person { .person {
@include make-md-column(6); @include make-md-column(6);
margin-top: 10px; margin-top: 10px;
@media (max-width: $screen-sm-min) {
width: 100%;
}
} }
.person .spark { .person .spark {
display: block; display: block;
background: #f3f3f3; background: #f3f3f3;
width: 100%;
} }
.person .area-contributor { .person .area-contributor {
......
...@@ -5,6 +5,7 @@ class Admin::AppearancesController < Admin::ApplicationController ...@@ -5,6 +5,7 @@ class Admin::AppearancesController < Admin::ApplicationController
end end
def preview def preview
render 'preview', layout: 'devise'
end end
def create def create
......
...@@ -50,8 +50,6 @@ module GitlabMarkdownHelper ...@@ -50,8 +50,6 @@ module GitlabMarkdownHelper
context[:project] ||= @project context[:project] ||= @project
text = Banzai.pre_process(text, context)
html = Banzai.render(text, context) html = Banzai.render(text, context)
context.merge!( context.merge!(
......
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
Maximum file size is 1MB. Pages are optimized for a 72x72 px header logo Maximum file size is 1MB. Pages are optimized for a 72x72 px header logo
.form-actions .form-actions
= f.submit 'Save', class: 'btn btn-save' = f.submit 'Save', class: 'btn btn-save append-right-10'
- if @appearance.persisted? - if @appearance.persisted?
= link_to 'Preview last save', preview_admin_appearances_path, class: 'btn', target: '_blank' = link_to 'Preview last save', preview_admin_appearances_path, class: 'btn', target: '_blank'
......
- page_title "Preview | Appearance" - page_title "Preview | Appearance"
%h3.page-title .login-box
Appearance settings - Preview .login-heading
%hr %h3 Existing user? Sign in
%form
.ui-box
.title
Sign-in page
%div
.login-page
.container
.content
.login-title
%h1= brand_title
%hr
.container
.content
.row
.col-sm-7
.brand-image
= brand_image
.brand_text
= brand_text
.col-sm-4
.login-box
%h3.page-title Sign in
= text_field_tag :login, nil, class: "form-control top", placeholder: "Username or Email" = text_field_tag :login, nil, class: "form-control top", placeholder: "Username or Email"
= password_field_tag :password, nil, class: "form-control bottom", placeholder: "Password" = password_field_tag :password, nil, class: "form-control bottom", placeholder: "Password"
= button_tag "Sign in", class: "btn-create btn" = button_tag "Sign in", class: "btn-create btn"
...@@ -39,9 +39,9 @@ ...@@ -39,9 +39,9 @@
- if project_nav_tab? :files - if project_nav_tab? :files
= nav_link(controller: %w(tree blob blame edit_tree new_tree find_file commit commits compare repositories tags branches releases network)) do = nav_link(controller: %w(tree blob blame edit_tree new_tree find_file commit commits compare repositories tags branches releases network)) do
= link_to project_files_path(@project), title: 'Code', class: 'shortcuts-tree' do = link_to project_files_path(@project), title: 'Repository', class: 'shortcuts-tree' do
%span %span
Code Repository
- if project_nav_tab? :pipelines - if project_nav_tab? :pipelines
= nav_link(controller: [:pipelines, :builds, :environments]) do = nav_link(controller: [:pipelines, :builds, :environments]) do
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
= render "projects/commits/head" = render "projects/commits/head"
%div{ class: (container_class) } %div{ class: (container_class) }
.row-content-block.second-block.content-component-block .sub-header-block
Compare branches, tags or commit ranges. Compare branches, tags or commit ranges.
%br %br
Fill input field with commit id like Fill input field with commit id like
......
- @no_container = true
- page_title "#{params[:from]}...#{params[:to]}" - page_title "#{params[:from]}...#{params[:to]}"
= render "projects/commits/head" = render "projects/commits/head"
%div{ class: (container_class) }
.row-content-block .sub-header-block.no-bottom-space
= render "form" = render "form"
- if @commits.present? - if @commits.present?
.prepend-top-default
= render "projects/commits/commit_list" = render "projects/commits/commit_list"
= render "projects/diffs/diffs", diffs: @diffs, project: @project, diff_refs: @diff_refs = render "projects/diffs/diffs", diffs: @diffs, project: @project, diff_refs: @diff_refs
- else - else
.light-well.prepend-top-default .light-well
.center .center
%h4 %h4
There isn't anything to compare. There isn't anything to compare.
......
...@@ -40,9 +40,3 @@ ...@@ -40,9 +40,3 @@
= render 'projects', projects: @forks = render 'projects', projects: @forks
- if @private_forks_count > 0
.private-forks-notice
= icon('lock fw', base: 'circle', class: 'fa-lg private-fork-icon')
%strong= pluralize(@private_forks_count, 'private fork')
%span you have no access to.
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
- unless @repository.gitlab_ci_yml - unless @repository.gitlab_ci_yml
%li.missing %li.missing
= link_to add_special_file_path(@project, file_name: '.gitlab-ci.yml') do = link_to add_special_file_path(@project, file_name: '.gitlab-ci.yml') do
Set up CI Set Up CI
- if @repository.commit - if @repository.commit
.content-block.second-block.white .content-block.second-block.white
......
...@@ -16,6 +16,12 @@ ...@@ -16,6 +16,12 @@
= render "shared/projects/project", project: project, skip_namespace: skip_namespace, = render "shared/projects/project", project: project, skip_namespace: skip_namespace,
avatar: avatar, stars: stars, css_class: css_class, ci: ci, use_creator_avatar: use_creator_avatar, avatar: avatar, stars: stars, css_class: css_class, ci: ci, use_creator_avatar: use_creator_avatar,
forks: forks, show_last_commit_as_description: show_last_commit_as_description forks: forks, show_last_commit_as_description: show_last_commit_as_description
- if @private_forks_count && @private_forks_count > 0
%li.project-row.private-forks-notice
= icon('lock fw', base: 'circle', class: 'fa-lg private-fork-icon')
%strong= pluralize(@private_forks_count, 'private fork')
%span you have no access to.
= paginate(projects, remote: remote, theme: "gitlab") if projects.respond_to? :total_pages = paginate(projects, remote: remote, theme: "gitlab") if projects.respond_to? :total_pages
- else - else
.nothing-here-block No projects found .nothing-here-block No projects found
......
...@@ -32,6 +32,7 @@ following locations: ...@@ -32,6 +32,7 @@ following locations:
- [Services](services.md) - [Services](services.md)
- [Session](session.md) - [Session](session.md)
- [Settings](settings.md) - [Settings](settings.md)
- [Sidekiq metrics](sidekiq_metrics.md)
- [System Hooks](system_hooks.md) - [System Hooks](system_hooks.md)
- [Tags](tags.md) - [Tags](tags.md)
- [Users](users.md) - [Users](users.md)
......
...@@ -10,9 +10,9 @@ Feature: Project Active Tab ...@@ -10,9 +10,9 @@ Feature: Project Active Tab
Then the active main tab should be Home Then the active main tab should be Home
And no other main tabs should be active And no other main tabs should be active
Scenario: On Project Code Scenario: On Project Repository
Given I visit my project's files page Given I visit my project's files page
Then the active main tab should be Code Then the active main tab should be Repository
And no other main tabs should be active And no other main tabs should be active
Scenario: On Project Issues Scenario: On Project Issues
...@@ -59,46 +59,46 @@ Feature: Project Active Tab ...@@ -59,46 +59,46 @@ Feature: Project Active Tab
And no other sub navs should be active And no other sub navs should be active
And the active main tab should be Settings And the active main tab should be Settings
# Sub Tabs: Code # Sub Tabs: Repository
Scenario: On Project Code/Files Scenario: On Project Repository/Files
Given I visit my project's files page Given I visit my project's files page
Then the active sub tab should be Files Then the active sub tab should be Files
And no other sub tabs should be active And no other sub tabs should be active
And the active main tab should be Code And the active main tab should be Repository
Scenario: On Project Code/Commits Scenario: On Project Repository/Commits
Given I visit my project's commits page Given I visit my project's commits page
Then the active sub tab should be Commits Then the active sub tab should be Commits
And no other sub tabs should be active And no other sub tabs should be active
And the active main tab should be Code And the active main tab should be Repository
Scenario: On Project Code/Network Scenario: On Project Repository/Network
Given I visit my project's network page Given I visit my project's network page
Then the active sub tab should be Network Then the active sub tab should be Network
And no other sub tabs should be active And no other sub tabs should be active
And the active main tab should be Code And the active main tab should be Repository
Scenario: On Project Code/Compare Scenario: On Project Repository/Compare
Given I visit my project's commits page Given I visit my project's commits page
And I click the "Compare" tab And I click the "Compare" tab
Then the active sub tab should be Compare Then the active sub tab should be Compare
And no other sub tabs should be active And no other sub tabs should be active
And the active main tab should be Code And the active main tab should be Repository
Scenario: On Project Code/Branches Scenario: On Project Repository/Branches
Given I visit my project's commits page Given I visit my project's commits page
And I click the "Branches" tab And I click the "Branches" tab
Then the active sub tab should be Branches Then the active sub tab should be Branches
And no other sub tabs should be active And no other sub tabs should be active
And the active main tab should be Code And the active main tab should be Repository
Scenario: On Project Code/Tags Scenario: On Project Repository/Tags
Given I visit my project's commits page Given I visit my project's commits page
And I click the "Tags" tab And I click the "Tags" tab
Then the active sub tab should be Tags Then the active sub tab should be Tags
And no other sub tabs should be active And no other sub tabs should be active
And the active main tab should be Code And the active main tab should be Repository
Scenario: On Project Issues/Browse Scenario: On Project Issues/Browse
Given I visit my project's issues page Given I visit my project's issues page
......
...@@ -8,21 +8,21 @@ Feature: Project Shortcuts ...@@ -8,21 +8,21 @@ Feature: Project Shortcuts
@javascript @javascript
Scenario: Navigate to files tab Scenario: Navigate to files tab
Given I press "g" and "f" Given I press "g" and "f"
Then the active main tab should be Code Then the active main tab should be Repository
Then the active sub tab should be Files Then the active sub tab should be Files
@javascript @javascript
Scenario: Navigate to commits tab Scenario: Navigate to commits tab
Given I visit my project's files page Given I visit my project's files page
Given I press "g" and "c" Given I press "g" and "c"
Then the active main tab should be Code Then the active main tab should be Repository
Then the active sub tab should be Commits Then the active sub tab should be Commits
@javascript @javascript
Scenario: Navigate to network tab Scenario: Navigate to network tab
Given I press "g" and "n" Given I press "g" and "n"
Then the active sub tab should be Network Then the active sub tab should be Network
And the active main tab should be Code And the active main tab should be Repository
@javascript @javascript
Scenario: Navigate to graphs tab Scenario: Navigate to graphs tab
......
...@@ -13,12 +13,12 @@ class Spinach::Features::ProjectFindFile < Spinach::FeatureSteps ...@@ -13,12 +13,12 @@ class Spinach::Features::ProjectFindFile < Spinach::FeatureSteps
end end
step 'I should see "find file" page' do step 'I should see "find file" page' do
ensure_active_main_tab('Code') ensure_active_main_tab('Repository')
expect(page).to have_selector('.file-finder-holder', count: 1) expect(page).to have_selector('.file-finder-holder', count: 1)
end end
step 'I fill in Find by path with "git"' do step 'I fill in Find by path with "git"' do
ensure_active_main_tab('Code') ensure_active_main_tab('Repository')
expect(page).to have_selector('.file-finder-holder', count: 1) expect(page).to have_selector('.file-finder-holder', count: 1)
end end
......
...@@ -8,8 +8,8 @@ module SharedProjectTab ...@@ -8,8 +8,8 @@ module SharedProjectTab
ensure_active_main_tab('Project') ensure_active_main_tab('Project')
end end
step 'the active main tab should be Code' do step 'the active main tab should be Repository' do
ensure_active_main_tab('Code') ensure_active_main_tab('Repository')
end end
step 'the active main tab should be Graphs' do step 'the active main tab should be Graphs' do
......
...@@ -7,10 +7,6 @@ module Banzai ...@@ -7,10 +7,6 @@ module Banzai
Renderer.render_result(text, context) Renderer.render_result(text, context)
end end
def self.pre_process(text, context)
Renderer.pre_process(text, context)
end
def self.post_process(html, context) def self.post_process(html, context)
Renderer.post_process(html, context) Renderer.post_process(html, context)
end end
......
...@@ -30,13 +30,9 @@ module Banzai ...@@ -30,13 +30,9 @@ module Banzai
end end
def self.render_result(text, context = {}) def self.render_result(text, context = {})
Pipeline[context[:pipeline]].call(text, context) text = Pipeline[:pre_process].to_html(text, context) if text
end
def self.pre_process(text, context) Pipeline[context[:pipeline]].call(text, context)
pipeline = Pipeline[:pre_process]
pipeline.to_html(text, context)
end end
# Perform post-processing on an HTML String # Perform post-processing on an HTML String
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment