【问题标题】:Rails: how to check CSS or JS code code from a string?Rails:如何从字符串中检查 CSS 或 JS 代码?
【发布时间】:2017-05-14 18:43:09
【问题描述】:

code 字符串中,我存储了一段代码,可以是 CSS、SASS、SCSS、JavaScript 或 CoffeeScript。 内容来自用户,我需要在保存到数据库之前验证语法。

我需要检查语法是否正确。目前,我正在使用一个有效的丑陋黑客。你有更好的解决方案吗?

def check_js
  if language == 'coffee'      # CoffeeScript
    CoffeeScript.compile code
  else                         # JavaScript
    Uglifier.compile code
  end
rescue ExecJS::RuntimeError => e
  errors.add :code, e.message
end

def check_css
  if language == 'css'         # CSS
    Sass::CSS.new(code).render
  else                         # SASS, SCSS
    Sass.compile code, syntax: language.to_sym
  end
rescue Sass::SyntaxError => e
  errors.add :code, e.message
end

【问题讨论】:

  • 我认为要找到更好的解决方案,看看你在哪里调用它并解释为什么需要它会非常有用。
  • @Caffeinated.tech 感谢您的建议,我添加了这句话,希望它更清楚“内容来自用户,我需要在保存到 satabase 之前验证语法。”跨度>
  • @dan-klasson 我猜你得到了最好的答案
  • @Benj 忘了给你点赞。如果我在你的鞋子里,我会做同样的事情。如果我能以某种方式改进你的代码,我会发布一个实际的答案。

标签: ruby-on-rails sass coffeescript


【解决方案1】:
# app/models/user.rb

class User < ActiveRecord::Base
  validates_with Validators::SyntaxValidator
end

# app/models/validators/syntax_validator.rb

class Validators::SyntaxValidator < ActiveModel::Validator
  def validate(record)
    @record = record

    case language
      when :coffee
        CoffeeScript.compile(code)
      when :javascript
        Uglifier.compile(code)
      when :css
        Sass::CSS.new(code).render
      when :sass
        Sass.compile code, syntax: language.to_sym
      when :scss
        Sass.compile code, syntax: language.to_sym
    end

    rescue Sass::SyntaxError => e
      errors.add :code, e.message

    rescue ExecJS::RuntimeError => e
      errors.add :code, e.message
  end
end

也许是这样的?你认为呢? http://api.rubyonrails.org/classes/ActiveModel/Validator.html

【讨论】:

    【解决方案2】:

    使用 Sass::CSS.new 给我一个未初始化的常量 Sass::CSS 错误,即使我安装了 sass 和 sass-rails gems。所以我发现了一个不同的宝石。

    https://github.com/w3c-validators/w3c_validators

    include W3CValidators
    validator = CSSValidator.new
    
    results = validator.validate_text(css_code)
    
    if results.errors.length > 0
      @success = false
      results.errors.each do |err|
        puts err.to_s
      end
    else
      @success = true
    end
    

    【讨论】:

      最近更新 更多