cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - ActiveLovehtmlicon-new-collectionicon-personicon-teamlog-outoctocatpop-outspinnerstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

            
              svg(viewBox="0 0 100 100" style="display:none")
  defs
    path#icon_love(d="M73.4,6c-10.2,0-19,5.7-23.4,14.1C45.5,11.7,36.7,6,26.6,6C11.9,6,0,18,0,32.7C0,68.9,50,94,50,94 s50-25.1,50-61.3C100,18,88.1,6,73.4,6L73.4,6z")
    path#icon_reply(d="M75.9,100C87,79.9,88.9,49.2,45.4,50.2V75L8,37.5L45.4,0v24.3C97.4,22.9,103.2,70.4,75.9,100z")
div(ng-app="comments" ng-controller="commentsCtrl")
  ul(ng-if="comments.length")
    li(ng-repeat="comment in comments")
      header
        h1(ng-if="comment.author.website.length == 0" ng-class="{ author: isAuthor(comment.author.email) }") {{ comment.author.name }}
        h1(ng-if="comment.author.website.length > 0" ng-class="{ author: isAuthor(comment.author.email) }")
          a(ng-href="//{{ comment.author.website }}") {{ comment.author.name }}
        button.love(ng-click="loveComment(comment.id)" ng-class="{ loved: comment.loved }")
          svg(viewBox="0 0 100 100")
            use(xlink:href="#icon_love")
        button.reply(ng-click="addReply(comment.author.name)")
          svg(viewBox="0 0 100 100")
            use(xlink:href="#icon_reply")
        img(ng-src="{{ getGravatar(comment.author.email) }}")
      article(ng-bind-html="parseContent(comment.content)")
  form(name="form" ng-submit="form.$valid && addNewComment()" novalidate)
    input(type="text" placeholder="First and second name" ng-pattern="/[a-zA-Z\.,\-]+/" ng-model="newComment.author.name" required)
    textarea(placeholder="Comment" ng-model="newComment.content" required)
    input(type="email" placeholder="Email" ng-model="newComment.author.email" required)
    input(type="url" placeholder="Website" ng-model="newComment.author.website")
    button.ripple(type="submit") Add comment
    img#newCommentAvatar(ng-src="{{ getGravatar(newComment.author.email) }}")
            
          
!
            
              $mainColor: #9a3

body
  max-width: 840px

ul
  padding-left: 80px
  list-style: none

  li
    background: #fff
    border-radius: 2px
    box-shadow: 0 1px 2px rgba(#000, .1)
    position: relative

    &:not(:first-child)
      margin-top: 20px

    &:before
      content: ''
      border-width: 10px 10px 10px 0
      border-style: solid
      border-color: transparent #fff
      position: absolute
      top: 10px
      left: -10px

    header
      border-bottom: 1px solid #e5e5e5
      display: flex

      *
        display: block

      h1
        padding-left: 20px
        font-weight: normal
        line-height: 40px
        flex-grow: 1

        a
          text-decoration: none
          display: inline-block

        &.author

          &, & *
            color: $mainColor

          &:after
            content: 'Author'
            margin: 10px 0 10px 10px
            padding: 0 5px
            background: $mainColor
            border-radius: 2px
            color: #fff
            font-size: 10px
            font-weight: normal
            text-transform: uppercase
            line-height: 20px
            position: absolute

      button
        padding: 10px

        svg
          width: 20px
          height: 20px

          *
            fill: #999

        &:hover
          svg *
            fill: #666

        &.loved
          svg *
            fill: #f66

      img
        width: 60px
        height: 60px
        background: #fff
        border: 4px solid #fff
        border-radius: 2px
        box-shadow: 0 1px 2px rgba(#000, .1)
        position: absolute
        top: 0
        left: -80px

    article
      padding: 20px
      white-space: pre-line
      overflow-x: hidden

      .reply
        color: $mainColor

      strong
        font-weight: 500

      em
        font-style: italic

      a
        text-decoration: underline

        &:hover
          text-decoration: none

      code
        font-family: 'Source Code Pro', monospace

form
  margin-top: 20px
  padding: 20px 20px 20px 100px
  background: #fff
  border-radius: 2px
  box-shadow: 0 1px 2px rgba(#000, .1)
  position: relative
  flex-wrap: wrap
  display: flex

  &:before
    content: ''
    border-width: 10px 10px 10px 0
    border-style: solid
    border-color: transparent rgba(#e5e5e5, .5)
    position: absolute
    top: 30px
    left: 90px

  input,
  textarea
    padding: 9px 20px
    width: 100%
    background: rgba(#e5e5e5, .5)
    display: block

    &:not(:first-child)
      margin-top: 2px

    &[type='email']
      width: 50%
      border-right: 1px solid #fff

    &[type='url']
      width: 50%
      border-left: 1px solid #fff

    &::placeholder
      color: #666

    &.ng-dirty.ng-invalid,
    &.ng-dirty.ng-invalid::placeholder
      color: #f66

  textarea
    padding: 20px
    height: 120px
    resize: none

  p
    margin-top: 10px
    padding: 10px 0
    width: 50%

    a
      text-decoration: underline

      &:hover
        text-decoration: none

  button
    margin: 10px auto 0
    padding: 10px 0
    width: 50%
    background: $mainColor
    border-radius: 2px
    color: #fff
    font-weight: normal
    text-align: center
    display: block

  img
    width: 60px
    height: 60px
    background: rgba(#e5e5e5, .5)
    border: 4px solid rgba(#e5e5e5, .5)
    border-radius: 2px
    position: absolute
    top: 20px
    left: 20px

@media (max-width: 440px)
  ul
    padding: 0

    li
      &:before
        content: none

      header
        img
          clip: rect(0,0,0,0)

        h1.author:after
          content: none

  form
    padding-left: 20px

    &:before
      content: none

    img
      clip: rect(0,0,0,0)

    input,
    textarea
      padding: 10px

    textarea
      height: 80px

    p,
    button
      margin: 10px 10px 0
      width: 100%

    p
      padding: 0
            
          
!
            
              angular.module 'comments', []
  .controller 'commentsCtrl', ($scope, $sce) ->

    postAuthorEmail = 'jan.kanty.pawelski@gmail.com'
    $scope.comments = [
      {
        id: 1
        author:
          name: 'Jan-Kanty Pawelski'
          email: 'jan.kanty.pawelski@gmail.com'
          website: 'pawelski.io'
        content: 'I made it! My awesome angular comment system. What do you think?'
        loved: false
      }
      {
        id: 2
        author:
          name: 'Tomasz Jakut'
          email: 'comandeer@comandeer.pl'
          website: 'comandeer.pl'
        content: 'Nice looking. Good job dude ;)'
        loved: true
      }
      {
        id: 3
        author:
          name: 'Jan-Kanty Pawelski'
          email: 'jan.kanty.pawelski@gmail.com'
          website: 'pawelski.io'
        content: '<span class="reply">@Tomasz Jakut</span> Thanks man. I tried hard.'
        loved: false
      }
      {
        id: 4
        author:
          name: 'Grzegorz Bąk'
          email: 'szary.elf@gmail.com'
          website: 'gregbak.com'
        content: 'Third! Amazing system man! By the way check my new website: <a href="//gregbak.com">http://gregbak.com</a>.'
        loved: false
      }
    ]
    $scope.newComment = {}


    markdown = (string) ->
      string = string.replace(/(@.+)@/g, '<span class="reply">$1</span>')
      
      string = string.replace(/\*\*(.+)\*\*/g, '<strong>$1</strong>')
      string = string.replace(/__(.+)__/g, '<strong>$1</strong>')

      string = string.replace(/\*(.+)\*/g, '<em>$1</em>')
      string = string.replace(/_(.+)_/g, '<em>$1</em>')

      string = string.replace(/``(.+)``/g, '<code>$1</code>')
      string = string.replace(/`(.+)`/g, '<code>$1</code>')

      return string

    $scope.parseContent = (content) ->
      return $sce.trustAsHtml(content)


    $scope.isAuthor = (email) ->
      return email is postAuthorEmail


    $scope.getGravatar = (email) ->
      if email is undefined
        email = ''

      hash = email.trim()
      hash = hash.toLowerCase()
      hash = md5 hash

      return '//gravatar.com/avatar/' + hash + '?s=104&d=identicon'


    $scope.loveComment = (commentId) ->
      for comment in $scope.comments
        if comment.id is commentId
          comment.loved = !comment.loved


    $scope.addReply = (author) ->
      if $scope.newComment.content is undefined
        $scope.newComment.content = ''

      if $scope.newComment.content.search('@' + author + '@') is -1
        if $scope.newComment.content[0] is '@'
          $scope.newComment.content = ', ' + $scope.newComment.content

        else
          $scope.newComment.content = ' ' + $scope.newComment.content

        $scope.newComment.content = '@' + author + '@' + $scope.newComment.content


    $scope.addNewComment = ->
      $scope.newComment.id = $scope.comments.length + 1
      $scope.newComment.author.website = $scope.newComment.author.website.replace(/https?:\/\/(www.)?/g, '')
      $scope.newComment.content = markdown($scope.newComment.content)
      $scope.newComment.loved = false

      $scope.comments.push $scope.newComment
      $scope.newComment = {}


    $scope.$watch 'newComment.email', (newValue, oldValue) ->
      newCommentAvatar = document.getElementById('newCommentAvatar')
      newCommentAvatar.src = $scope.getGravatar($scope.newComment.email)
            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.
Loading ..................

Console