Update MarkdownSectionController with support for editing
This allows the MarkdownSectionController and ItemPageController to work together to begin an editing session for an item description.
This commit is contained in:
@@ -66,7 +66,7 @@ Event.route = 'route'
|
|||||||
Event.sort = 'sort'
|
Event.sort = 'sort'
|
||||||
Event.sync = 'sync' # model, response
|
Event.sync = 'sync' # model, response
|
||||||
Event.transitionEnd = (->
|
Event.transitionEnd = (->
|
||||||
return unless document?
|
return 'transitionend' unless document?
|
||||||
transitions =
|
transitions =
|
||||||
'WebkitTransition': 'webkitTransitionEnd'
|
'WebkitTransition': 'webkitTransitionEnd'
|
||||||
'MozTransition': 'transitionend'
|
'MozTransition': 'transitionend'
|
||||||
@@ -88,6 +88,10 @@ Key.Escape = 27
|
|||||||
Key.UpArrow = 38
|
Key.UpArrow = 38
|
||||||
Key.DownArrow = 40
|
Key.DownArrow = 40
|
||||||
|
|
||||||
|
exports.GitHub = GitHub = {}
|
||||||
|
GitHub.file = {}
|
||||||
|
GitHub.file.itemDescription = _.template "/data/<%= modSlug %>/items/<%= itemSlug %>/item.cg"
|
||||||
|
|
||||||
exports.Login = Login = {}
|
exports.Login = Login = {}
|
||||||
Login.authorizeUrl = _.template "https://github.com/login/oauth/authorize" +
|
Login.authorizeUrl = _.template "https://github.com/login/oauth/authorize" +
|
||||||
"?client_id=<%= clientId %>&scope=public_repo&state=<%= state %>"
|
"?client_id=<%= clientId %>&scope=public_repo&state=<%= state %>"
|
||||||
|
|||||||
@@ -16,8 +16,10 @@ MarkdownSectionController = require './markdown_section_controller'
|
|||||||
PageController = require './page_controller'
|
PageController = require './page_controller'
|
||||||
VideoController = require './video_controller'
|
VideoController = require './video_controller'
|
||||||
_ = require 'underscore'
|
_ = require 'underscore'
|
||||||
|
w = require 'when'
|
||||||
{Duration} = require '../constants'
|
{Duration} = require '../constants'
|
||||||
{Event} = require '../constants'
|
{Event} = require '../constants'
|
||||||
|
{GitHub} = require '../constants'
|
||||||
{Text} = require '../constants'
|
{Text} = require '../constants'
|
||||||
{Url} = require '../constants'
|
{Url} = require '../constants'
|
||||||
|
|
||||||
@@ -26,6 +28,7 @@ _ = require 'underscore'
|
|||||||
module.exports = class ItemPageController extends PageController
|
module.exports = class ItemPageController extends PageController
|
||||||
|
|
||||||
constructor: (options={})->
|
constructor: (options={})->
|
||||||
|
if not options.client? then throw new Error 'options.client is required'
|
||||||
if not options.itemSlug? then throw new Error 'options.itemSlug is required'
|
if not options.itemSlug? then throw new Error 'options.itemSlug is required'
|
||||||
if not options.imageLoader? then throw new Error 'options.imageLoader is required'
|
if not options.imageLoader? then throw new Error 'options.imageLoader is required'
|
||||||
if not options.modPack? then throw new Error 'options.modPack is required'
|
if not options.modPack? then throw new Error 'options.modPack is required'
|
||||||
@@ -35,9 +38,12 @@ module.exports = class ItemPageController extends PageController
|
|||||||
|
|
||||||
super options
|
super options
|
||||||
|
|
||||||
|
@client = options.client
|
||||||
@imageLoader = options.imageLoader
|
@imageLoader = options.imageLoader
|
||||||
@modPack = options.modPack
|
@modPack = options.modPack
|
||||||
@_itemSlug = options.itemSlug
|
|
||||||
|
@_editingFile = null
|
||||||
|
@_itemSlug = options.itemSlug
|
||||||
|
|
||||||
@modPack.on Event.change, => @tryRefresh()
|
@modPack.on Event.change, => @tryRefresh()
|
||||||
|
|
||||||
@@ -58,12 +64,17 @@ module.exports = class ItemPageController extends PageController
|
|||||||
onDidRender: ->
|
onDidRender: ->
|
||||||
@adsenseController = @addChild AdsenseController, '.view__adsense', model:'sidebar_skyscraper'
|
@adsenseController = @addChild AdsenseController, '.view__adsense', model:'sidebar_skyscraper'
|
||||||
|
|
||||||
options = editable:true, imageLoader:@imageLoader, modPack:@modPack, show:false
|
options = imageLoader:@imageLoader, modPack:@modPack, show:false
|
||||||
@_descriptionController = @addChild MarkdownSectionController, '.section.description', options
|
|
||||||
@_similarItemsController = @addChild ItemGroupController, '.view__item_group.similar', options
|
@_similarItemsController = @addChild ItemGroupController, '.view__item_group.similar', options
|
||||||
@_usedAsToolToMakeController = @addChild ItemGroupController, '.view__item_group.usedAsToolToMake', options
|
@_usedAsToolToMakeController = @addChild ItemGroupController, '.view__item_group.usedAsToolToMake', options
|
||||||
@_usedToMakeController = @addChild ItemGroupController, '.view__item_group.usedToMake', options
|
@_usedToMakeController = @addChild ItemGroupController, '.view__item_group.usedToMake', options
|
||||||
|
|
||||||
|
@_descriptionController = @addChild MarkdownSectionController, '.section.description',
|
||||||
|
editable: true
|
||||||
|
modPack: @modPack
|
||||||
|
beginEditing: => @_beginEditingDescription()
|
||||||
|
endEditing: => @_endEditingDescription()
|
||||||
|
|
||||||
@$byline = @$('.byline')
|
@$byline = @$('.byline')
|
||||||
@$bylineLink = @$('.byline a')
|
@$bylineLink = @$('.byline a')
|
||||||
@$descriptionSection = @$('.description')
|
@$descriptionSection = @$('.description')
|
||||||
@@ -126,6 +137,23 @@ module.exports = class ItemPageController extends PageController
|
|||||||
|
|
||||||
# Private Methods ##############################################################################
|
# Private Methods ##############################################################################
|
||||||
|
|
||||||
|
_beginEditingDescription: ->
|
||||||
|
if not global.router.user?
|
||||||
|
global.router.login()
|
||||||
|
return w.reject new Error 'must be logged in to edit'
|
||||||
|
|
||||||
|
if not @model.item?
|
||||||
|
return w.reject new Error 'must have an item'
|
||||||
|
|
||||||
|
@client.fetchFile file:GitHub.file.itemDescription modSlug:@_itemSlug.mod, itemSlug:@_itemSlug.item
|
||||||
|
.then (fileRecord)=>
|
||||||
|
@_editingFile = fileRecord
|
||||||
|
@model.item.parse fileRecord.content
|
||||||
|
@_descriptionController.model = @model.item.description
|
||||||
|
|
||||||
|
_endEditingDescription: ->
|
||||||
|
return w(true).delay(1000)
|
||||||
|
|
||||||
_refreshByline: ->
|
_refreshByline: ->
|
||||||
mod = @model.item?.modVersion?.mod
|
mod = @model.item?.modVersion?.mod
|
||||||
if mod?.name?.length > 0
|
if mod?.name?.length > 0
|
||||||
|
|||||||
@@ -10,94 +10,118 @@ convertMarkdown = require 'marked'
|
|||||||
_ = require 'underscore'
|
_ = require 'underscore'
|
||||||
{Event} = require '../constants'
|
{Event} = require '../constants'
|
||||||
{Url} = require '../constants'
|
{Url} = require '../constants'
|
||||||
|
w = require 'when'
|
||||||
|
|
||||||
########################################################################################################################
|
########################################################################################################################
|
||||||
|
|
||||||
module.exports = class MarkdownSectionController extends BaseController
|
module.exports = class MarkdownSectionController extends BaseController
|
||||||
|
|
||||||
@State = State =
|
@State = State =
|
||||||
viewing: 'viewing'
|
appologizing: 'applogizing'
|
||||||
editing: 'editing'
|
confirming: 'confirming'
|
||||||
previewing: 'previewing'
|
editing: 'editing'
|
||||||
error: 'error'
|
previewing: 'previewing'
|
||||||
|
viewing: 'viewing'
|
||||||
|
waiting: 'waiting'
|
||||||
|
|
||||||
constructor: (options={})->
|
constructor: (options={})->
|
||||||
|
@_state = State.waiting
|
||||||
|
|
||||||
if not options.modPack? then throw new Error 'options.modPack is required'
|
if not options.modPack? then throw new Error 'options.modPack is required'
|
||||||
options.editable ?= false
|
options.model ?= null
|
||||||
options.imageBase ?= ''
|
options.templateName = 'markdown_section'
|
||||||
options.model ?= ''
|
|
||||||
options.title ?= 'Description'
|
|
||||||
options.templateName = 'markdown_section'
|
|
||||||
super options
|
super options
|
||||||
|
|
||||||
@imageBase = options.imageBase
|
@confirmactionMessage = options.confirmationMessage
|
||||||
@modPack = options.modPack
|
@confirmDuration = options.confirmationDuration ?= 5000
|
||||||
@title = options.title
|
@imageBase = options.imageBase ?= ''
|
||||||
|
@modPack = options.modPack
|
||||||
|
@title = options.title ?= 'Description'
|
||||||
|
|
||||||
@_editable = options.editable
|
# @_beginEditing must be a function returning a promise which resolves when all actions necessary prior to an
|
||||||
@_state = State.viewing
|
# editing session have been completed (e.g., loading the latest content from a remote server). The promise must
|
||||||
|
# reject if an error occured which should prevent editing.
|
||||||
|
@_beginEditing = options.beginEditing
|
||||||
|
|
||||||
|
# @_endEditing must be a function returning a promise which resolves when the model of this controller has been
|
||||||
|
# saved however is appropriate. The promise must reject if saving failed for some reason.
|
||||||
|
@_endEditing = options.endEditing
|
||||||
|
|
||||||
# Event Methods ################################################################################
|
# Event Methods ################################################################################
|
||||||
|
|
||||||
onCancelClicked: (event)->
|
onCancelClicked: (event)->
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
@_state = State.viewing
|
@model = @_originalModel
|
||||||
@_updateStateVisibility()
|
@state = State.viewing
|
||||||
|
|
||||||
onEditClicked: (event)->
|
onEditClicked: (event)->
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
return unless @editable
|
||||||
|
|
||||||
if global.router.user?
|
@_originalModel = "#{@model}"
|
||||||
@_state = State.editing
|
@state = State.waiting
|
||||||
@_updateStateVisibility()
|
@_beginEditing()
|
||||||
else
|
.then =>
|
||||||
global.router.login()
|
@state = State.editing
|
||||||
|
.catch (e)=>
|
||||||
|
logger.warning "cannot begin editing: #{e.stack}"
|
||||||
|
@state = State.appologizing
|
||||||
|
w(true).delay(@confirmDuration).then => @state = State.viewing
|
||||||
|
|
||||||
onPreviewClicked: (event)->
|
onPreviewClicked: (event)->
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
@_state = State.preview
|
@state = State.previewing
|
||||||
@_updateStateVisibility()
|
|
||||||
|
|
||||||
onReturnClicked: (event)->
|
onReturnClicked: (event)->
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
@_state = State.editing
|
@state = State.editing
|
||||||
@_updateStateVisibility()
|
|
||||||
|
|
||||||
onSaveClicked: (event)->
|
onSaveClicked: (event)->
|
||||||
# TODO: implement logic to actually save changes
|
event.preventDefault()
|
||||||
@onCancelClicked event
|
|
||||||
|
nextState = State.viewing
|
||||||
|
@state = State.waiting
|
||||||
|
@_endEditing()
|
||||||
|
.then =>
|
||||||
|
@state = State.confirming
|
||||||
|
.catch (e)=>
|
||||||
|
logger.error "failed to end editing: #{e}"
|
||||||
|
@state = State.appologizing
|
||||||
|
nextState = State.editing
|
||||||
|
.delay @confirmDuration
|
||||||
|
.then =>
|
||||||
|
@state = nextState
|
||||||
|
|
||||||
onTextChanged: (event)->
|
onTextChanged: (event)->
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
@_updatePreview()
|
@model = @$textarea.val()
|
||||||
@_updateSizer()
|
|
||||||
|
|
||||||
# Property Methods #############################################################################
|
# Property Methods #############################################################################
|
||||||
|
|
||||||
isEditable: ->
|
isEditable: ->
|
||||||
return @_editable
|
return _.isFunction(@_beginEditing) and _.isFunction(@_endEditing)
|
||||||
|
|
||||||
setEditable: (editable)->
|
getState: ->
|
||||||
return if @_editable is editable
|
return @_state
|
||||||
@_editable = editable
|
|
||||||
@tryRefresh()
|
setState: (newState)->
|
||||||
|
oldState = @_state
|
||||||
|
return if oldState is newState
|
||||||
|
@_state = newState
|
||||||
|
|
||||||
|
logger.verbose => "MarkdownSectionController.#{@cid} changed state from #{oldState} to #{newState}"
|
||||||
|
@trigger Event.change + ':state', this, oldState, newState
|
||||||
|
@_updateStateVisibility()
|
||||||
|
|
||||||
Object.defineProperties @prototype,
|
Object.defineProperties @prototype,
|
||||||
editable: {get:@prototype.isEditable, set:@prototype.setEditable}
|
editable: {get:@prototype.isEditable}
|
||||||
|
state: {get:@prototype.getState, set:@prototype.setState}
|
||||||
|
|
||||||
# BaseController Overrides #####################################################################
|
# BaseController Overrides #####################################################################
|
||||||
|
|
||||||
onDidRender: ->
|
onDidRender: ->
|
||||||
@$buttonPanel = @$('.buttons')
|
|
||||||
@$cancelButton = @$('button.cancel')
|
|
||||||
@$editButton = @$('button.edit')
|
|
||||||
@$editorPanel = @$('.editor')
|
|
||||||
@$errorPanel = @$('.error')
|
|
||||||
@$errorText = @$('.error p')
|
@$errorText = @$('.error p')
|
||||||
@$markdownPanel = @$('.markdown')
|
@$markdownPanel = @$('.markdown')
|
||||||
@$previewButton = @$('button.preview')
|
|
||||||
@$returnButton = @$('button.return')
|
|
||||||
@$saveButton = @$('button.save')
|
|
||||||
@$sizer = @$('.sizer')
|
@$sizer = @$('.sizer')
|
||||||
@$textarea = @$('textarea')
|
@$textarea = @$('textarea')
|
||||||
@$title = @$('h2')
|
@$title = @$('h2')
|
||||||
@@ -107,17 +131,23 @@ module.exports = class MarkdownSectionController extends BaseController
|
|||||||
refresh: ->
|
refresh: ->
|
||||||
@$title.html @title
|
@$title.html @title
|
||||||
|
|
||||||
@$textarea.val @model
|
|
||||||
|
|
||||||
if @editable
|
|
||||||
@show @$buttonPanel
|
|
||||||
else
|
|
||||||
@hide @$buttonPanel
|
|
||||||
|
|
||||||
@_updateSizer()
|
@_updateSizer()
|
||||||
@_updatePreview()
|
@_updatePreview()
|
||||||
|
@_updateStateVisibility()
|
||||||
super
|
super
|
||||||
|
|
||||||
|
onWillChangeModel: (oldModel, newModel)->
|
||||||
|
result = super oldModel, newModel
|
||||||
|
|
||||||
|
if @state is State.waiting and newModel?
|
||||||
|
@state = State.viewing
|
||||||
|
else if not newModel?
|
||||||
|
@state = State.waiting
|
||||||
|
|
||||||
|
@$textarea.val newModel
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
# Backbone.View Overrides ######################################################################
|
# Backbone.View Overrides ######################################################################
|
||||||
|
|
||||||
events: ->
|
events: ->
|
||||||
@@ -147,35 +177,66 @@ module.exports = class MarkdownSectionController extends BaseController
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
_updateSizer: ->
|
_updateSizer: ->
|
||||||
text = @$textarea.val()
|
text = @model
|
||||||
text = text.replace /\n/g, '<br>'
|
if @model?
|
||||||
|
text = text.replace /\n/g, '<br>'
|
||||||
|
|
||||||
@$sizer.html text
|
@$sizer.html text
|
||||||
|
|
||||||
_updatePreview: ->
|
_updatePreview: ->
|
||||||
text = @$textarea.val()
|
text = @model
|
||||||
text = @_convertWikiLinks text
|
if @model?
|
||||||
text = @_convertImageLinks text
|
text = @_convertWikiLinks text
|
||||||
|
text = @_convertImageLinks text
|
||||||
|
text = convertMarkdown text
|
||||||
|
|
||||||
@$markdownPanel.html convertMarkdown text
|
@$markdownPanel.html text
|
||||||
|
|
||||||
_updateStateVisibility: ->
|
_updateStateVisibility: ->
|
||||||
toHide = []
|
return if @_lastUpdatedState is @state
|
||||||
toShow = []
|
@_lastUpdatedState = @state
|
||||||
|
|
||||||
|
elements =
|
||||||
|
appologizingPanel: @$('.appologizing')
|
||||||
|
buttonPanel: @$('.buttons')
|
||||||
|
cancelButton: @$('button.cancel')
|
||||||
|
confirmingPanel: @$('.confirming')
|
||||||
|
editButton: @$('button.edit')
|
||||||
|
editorPanel: @$('.editor')
|
||||||
|
errorPanel: @$('.error')
|
||||||
|
markdownPanel: @$markdownPanel
|
||||||
|
previewButton: @$('button.preview')
|
||||||
|
returnButton: @$('button.return')
|
||||||
|
saveButton: @$('button.save')
|
||||||
|
waitingPanel: @$('.waiting')
|
||||||
|
|
||||||
|
visible = {}
|
||||||
errorText = ''
|
errorText = ''
|
||||||
|
|
||||||
if @_state is State.viewing
|
if @state is State.appologizing
|
||||||
toHide = [@$cancelButton, @$editorPanel, @$errorPanel, @$previewButton, @$returnButton, @$saveButton]
|
visible = appologizingPanel:true
|
||||||
toShow = [@$editButton, @$markdownPanel]
|
else if @state is State.confirming
|
||||||
else if @_state is State.editing
|
visible = confirmingPanel:true
|
||||||
toHide = [@$editButton, @$errorPanel, @$markdownPanel, @$previewButton, @$returnButton]
|
else if @state is State.editing
|
||||||
toShow = [@$cancelButton, @$editorPanel, @$previewButton, @$saveButton]
|
visible = buttonPanel:true, cancelButton:true, editorPanel:true, previewButton:true, saveButton:true
|
||||||
else if @_state is State.preview
|
else if @state is State.previewing
|
||||||
toHide = [@$cancelButton, @$editButton, @$editorPanel, @$previewButton, @$saveButton]
|
visible = buttonPanel:true, errorPanel:true, markdownPanel:true, returnButton:true
|
||||||
toShow = [@$errorPanel, @$markdownPanel, @$returnButton]
|
|
||||||
errorText = "remember: your changes aren't saved yet!"
|
errorText = "remember: your changes aren't saved yet!"
|
||||||
# else if @_state is State.error
|
else if @state is State.viewing
|
||||||
# TODO: Implement change to error state
|
visible = markdownPanel:true
|
||||||
|
if @editable then _.extend visible, {buttonPanel:true, editButton:true}
|
||||||
|
else # assume any unknown state is the same as "waiting"
|
||||||
|
visible = waitingPanel:true
|
||||||
|
|
||||||
|
toHide = ($el for name, $el of elements when not visible[name])
|
||||||
|
toShow = ($el for name, $el of elements when visible[name])
|
||||||
|
|
||||||
|
if toHide.length > 0
|
||||||
|
@hide $el for $el in toHide
|
||||||
|
if toShow.length > 0
|
||||||
|
@once Event.animate.hide.finish, =>
|
||||||
|
@show $el for $el in toShow
|
||||||
|
else if toShow.length > 0
|
||||||
|
@show $el for $el in toShow
|
||||||
|
|
||||||
@hide $el for $el in toHide
|
|
||||||
@once Event.animate.hide.finish, => @show $el for $el in toShow
|
|
||||||
@$errorText.html errorText
|
@$errorText.html errorText
|
||||||
|
|||||||
@@ -8,11 +8,11 @@
|
|||||||
.view__markdown_section.section
|
.view__markdown_section.section
|
||||||
h2
|
h2
|
||||||
.panel
|
.panel
|
||||||
.markdown.hideable
|
.waiting.hideable: img(src='/images/wait.gif')
|
||||||
|
.markdown.hideable.hidden
|
||||||
.editor.hideable.hidden
|
.editor.hideable.hidden
|
||||||
textarea
|
textarea
|
||||||
.sizer
|
.sizer
|
||||||
.images.hideable.hidden
|
|
||||||
.buttons.hideable.hidden
|
.buttons.hideable.hidden
|
||||||
.error.hideable.hidden: p
|
.error.hideable.hidden: p
|
||||||
button.return.hideable.hidden return
|
button.return.hideable.hidden return
|
||||||
@@ -20,3 +20,9 @@
|
|||||||
button.preview.hideable.hidden preview
|
button.preview.hideable.hidden preview
|
||||||
button.save.hideable.hidden save
|
button.save.hideable.hidden save
|
||||||
button.edit.hideable edit
|
button.edit.hideable edit
|
||||||
|
.confirming.hideable.hidden
|
||||||
|
p Thanks for your help!
|
||||||
|
p Your changes will appear on the site in a few minutes.
|
||||||
|
.appologizing.hideable.hidden
|
||||||
|
p Sorry, but something went wrong.
|
||||||
|
p Please try again after a few moments.
|
||||||
|
|||||||
@@ -7,6 +7,51 @@ All rights reserved.
|
|||||||
|
|
||||||
.view__markdown_section {
|
.view__markdown_section {
|
||||||
|
|
||||||
|
.appologizing, .confirming {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
p {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
margin: 1em auto;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
font-size: $font-size-x-large;
|
||||||
|
margin-top: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 4em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttons {
|
||||||
|
position: relative; width: 100%;
|
||||||
|
|
||||||
|
text-align: right;
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin: 0.66em 0 0 0.66em;
|
||||||
|
min-width: 6.66em;
|
||||||
|
padding: 0.25em 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
background: none;
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: $color-error-new;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.editor {
|
.editor {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
@@ -40,28 +85,12 @@ All rights reserved.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.buttons {
|
.waiting {
|
||||||
position: relative; width: 100%;
|
position: relative; min-height: 20em; width: 100%;
|
||||||
|
|
||||||
text-align: right;
|
img {
|
||||||
|
position: absolute; top: 50%; left: 50%;
|
||||||
button {
|
@include transform(translate(-50%, -50%));
|
||||||
margin: 0.66em 0 0 0.66em;
|
|
||||||
min-width: 6.66em;
|
|
||||||
padding: 0.25em 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error {
|
|
||||||
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
background: none;
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
p {
|
|
||||||
color: $color-error-new;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 9.1 KiB |
Reference in New Issue
Block a user