В CoffeeScript благоустройства и рефакторинг


Как я ни старалась, я не могу показаться, чтобы получить этот код CoffeeScript, чтобы выглядеть красиво (хотелось бы думать, что это возможно). Я пробовал оба JavaScript и CoffeeScript. Просто чтобы быть ясно, этот код работает хорошо, но тяжело читать, по причинам, которые я не могу определить.

Как она может быть преобразована, реорганизована, и какие изменения в стиль кодирования может быть сделано, чтобы сделать его более привлекательным для чтения?

define [
  "plugins/ui/ui",
  "./js/highlight"
], (ui, highlight) ->
  editor = {}

  jQuery ($) ->
    # A widget to view source code.
    $.widget 'core.editor',
      _create: ->
        $editor = $(this.element)
        $editor
          .addClass('editor')
          .append($('<ul spellcheck="false" contenteditable> <li></li> </ul>'))

        # Move the gutter along with the editable area.
        this.lines().bind 'scroll', (event) ->
          $this = $(this)
          $this.siblings(".gutter").css(top: $this.scrollTop() * -1)

      # Highlight the sourceview using the given language.
      # The language's JSON rule file is loaded.
      highlight: (language) ->
        this.language = language
        require ["text!plugins/editor/js/#{ language }.json"], (json) =>
          this._rules = JSON.parse(json)
          return

      # Update the `left` of the `<ul>` based on the gutter width.
      # Each time the number of digits in the gutter changes, it becomes wider or
      # narrower, and the editor needs the shift accordingly.
      updateGutterWidth: () ->
        # The `8` is the gutter's left padding.
        this.lines().css(left: this.gutter().width() + 8)

      # Add or remove line numbers if the number of lines has changed.
      # `change` is a modification the the line count (In case the character was not yet
      # typed).
      updateLineNumbers: (change = 0) ->
        $gutter = this.gutter()
        count =   this.lines().children("li").length
        current = $gutter.children("span").length

        count += change

        # Add lines
        if (count > current)
          for i in [current..(count - 1)]
            ele = document.createElement("span")
            ele.innerText = "#{ i + 1 }"
            $gutter[0].appendChild(ele)
        # Remove lines
        else if (current > count)
          for j in [count..(current - 1)]
            $gutter.children("span:last-child").remove()

        this.updateGutterWidth() if current != count
        return

      # Set whether or not the gutter should be visible.
      lineNumbers: (bool) ->
        if bool == true and !this.number
          $(this.element)
            .prepend('<div class="gutter"></div>')
          this.lines()
            .css(left: 20)
          this.updateLineNumbers()
        else if bool == false and this.number
          this.gutter().remove()
          $(this.element)
            .css(left: 1)
        this.number = bool

      # Return the gutter (a jQuery object).
      gutter: () ->
        this._gutter ?= $(this.element).children("div.gutter")
        return this._gutter

      # Return a jQuery `<ul>`. Each `<li>` is a line of the source viewer.
      lines: ->
        return $(this.element).children('ul')

      # A hash of syntax highlighting rules.
      rules: ->
        return this._rules

    # Re-highlight the text.
    $(".editor > ul").live 'keyup', (event) ->
      # 13:              Enter
      # 37, 38, 39, 40:  Arrow Keys
      # 33, 34:          Page up / down
      # 16, 17, 18, 91:  Shift, Ctrl, Alt, Meta
      # 35, 36:          Home / end
      if !(event.which in [13, 37, 38, 39, 40, 33, 34, 16, 17, 18, 91, 35, 36]) and !event.altKey and !event.ctrlKey
        # Prevent an annoying error when backspacing to the beginning of a line.
        selection = window.getSelection()
        # Store the cursor position before highlighting.
        cursorPos = selection.getRangeAt(0)
        if cursorPos.getClientRects()[0]
          clickx = cursorPos.getClientRects()[0].left
          clicky = cursorPos.getClientRects()[0].top
          # Highlight
          $li = $(selection.focusNode).closest("li")
          rules = $li.closest(".editor").editor('rules')
          highlight.highlight($li, rules)
          # Restore cursor position.
          cursorPos = document.caretRangeFromPoint(clickx, clicky)
          window.getSelection().addRange(cursorPos)

    # Line numbering update.
    $(".editor > ul").live 'keydown', (event) ->
      # Redo line numbering for Enter, Backspace, Delete.
      if (event.which in [13, 8, 46])
        $this = $(this)
        newline = switch event.which
          when 13 then 1
          when 8  then -1
          else 0
        $this.parent().editor('updateLineNumbers', newline)
        # Correction
        setTimeout(() ->
          $this.parent().editor('updateLineNumbers', 0)
        , 300)




    # ##################### MAIN ##########################
    $(".frame").frame('tabs').last().tab("content")
      .append("<div id='sourceview'></div>")
    $("#sourceview")
      .css
        position: 'absolute'
        left:   1
        right:  1
        top:    1
        bottom: 1
      .editor()
      .editor('theme', 'plugins/editor/themes/idlefingers.css')
      .editor("highlight", "javascript")
      .editor("lineNumbers", true)


  return editor


4319
11
задан 25 марта 2011 в 08:03 Источник Поделиться
Комментарии
3 ответа

Да, CoffeeScript и не улучшить метод цепочки, из которых jQuery это так любят. Пару трюков. Во-первых, вспомните, как мощный деконструкция является

например

    if cursorPos.getClientRects()[0]
clickx = cursorPos.getClientRects()[0].left
clicky = cursorPos.getClientRects()[0].top

может быть

if r = cursorPos.getClientRects()[0]
{left, top} = r

также имейте в виду,

 @gutter

такой же, как и

 this.gutter

и

 highlight: (language) ->
this.language = language

может быть написано

 highlight: (@language) ->

Наконец, рассмотреть вопрос об использовании крышек для чего-то вы продолжаете делать, если производительность действительно критична.

например

$this.parent().editor('updateLineNumbers', newline)
setTimeout(() ->
$this.parent().editor('updateLineNumbers', 0)
, 300)

может быть

updateLineNumbers = (p) -> $this.parent().editor 'updateLineNumbers', p
updateLineNumbers newLine
after 300, () -> updateLineNumbers 0

11
ответ дан 7 июля 2011 в 06:07 Источник Поделиться

Еще одна вещь. Я почти всегда переписываю собственную версию setTimeout и setInterval, когда с помощью CoffeeScript, так что я могу использовать синтаксис чище, когда обратные вызовы являются последним аргументом.



after = (ms, cb) -> setTimeout cb, ms
every = (ms, cb) -> setInterval cb, ms

// that way, instead of this
setTimeout(() ->
doSomething()
doMore()
), 100)

// you can use this
after 100, () ->
doSomething()
doMore()


12
ответ дан 6 мая 2011 в 09:05 Источник Поделиться

Вот несколько простых советов:


  1. Поставить несколько пробелов между строками кода. Пробелы будет легче читать

  2. Я заметил, что вы используете два пробела для отступов. В общем, четыре пробела (или Tab) для более читабельный код

  3. Не разбивать строки на цепочку методов, если у вас есть тонны из них. Например, $(этот.элемент).УСБ(осталось: 1) все могут идти по одной линии без проблем. Если у вас больше чем 2 или 3, размещение каждой цепным методом на новой строке-это хорошая идея.

  4. Просто на комментарии. Комментирование кода-это хорошо, но слишком много писать, и это тормозит удобочитаемость кода. Если вам нужно писать много вещей, положить его в вместо внесения документации. Например, вы не должны включать клавиш, все эти цифры.

  5. А не передать длинную строку в качестве аргумента функции, сохранить его в локальной переменной на предыдущей строке, а затем передать эту переменную. Вместо:

    $(этот).код HTML('bigass HTML-строку');

    сделать это:

    ул. htmlStr = 'bigass HTML-код";

    $(этот).формате HTML(htmlStr);


  6. Воспользуйтесь синтаксис массива в CoffeeScript это

    ключи = [
    13
    37, 38, 39, 40
    33, 34
    16, 17, 18, 91
    35, 36
    ]


  7. Использовать свойство@, который в CoffeeScript делает доступными как раз для этого.собственность

  8. Попробовать Программирование с классами, и сохраняя как можно больше Привязок событий jQuery в отдельный участок кода. Таким образом, вы можете сохранить все $'S и другие jQuery и мусор из кода, который на самом деле делает ваши приложения работать. Организация вашего кода в структурированную иерархию классов будет ввести столь необходимую модульность для вашего кодирования. Разбивая куски часто используемого кода в модули многоразовые позволит сделать вещи проще для чтения и поощрения лучших практик.

8
ответ дан 14 апреля 2011 в 07:04 Источник Поделиться