Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
el-ace / lib / el-ace / el-ace.rb
Size: Mime:
EUtils.register_extra_engines!

module EL
  module Ace
    def self.included base
      base.mount_controller base.const_set(:ELAceController, Class.new(E) {
        include EL::AceHelpers

        map 'el-ace-controller'
        engine :Slim
        view_prefix '/'
        view_fullpath File.expand_path('../templates', __FILE__).freeze
        layout false

        def editor
          @textarea_id, @opts = env[:TEXTAREA_ID].to_s, env[:EDITOR_OPTS].dup
          @editor_id = normalize_editor_id(@textarea_id)
          @textarea_id = ('#' << @textarea_id).freeze
          @snippets = normalize_snippets(@opts.delete(:snippets))
          render
        end

        def get_assets(*)
          env['PATH_INFO'] = env['PATH_INFO'].to_s.sub(self.class::ASSETS_REGEXP, '')
          send_files self.class::ASSETS_PATH
        end
      })

      base.class_exec do

        private
        # @param [String] textarea_id
        # @param [Hash] opts
        # @option opts [String] :mode
        # @option opts [String] :file file name to guess mode by
        # @option opts [Boolean] :readonly
        # @option opts [Array] :snippets
        # @option opts [String|Proc] :toolbar_prepend
        #   a String or a Proc returning a String to be prepended to toolbar
        # @option opts [String|Proc] :toolbar_append
        #   a String or a Proc returning a String to be appended to toolbar
        # @option opts [String]  :save_button_selector
        #   a DOM selector for save button. by default .saveButton used.
        #   el-ace will update the content of textarea when save button hovered.
        #   this could also be done by listening onchange event,
        #   but page may become huge and slow on bigger documents.
        def ace textarea_id, opts = {}
          fetch self.class::ELAceController, :editor, params do |env|
            env.update TEXTAREA_ID: textarea_id, EDITOR_OPTS: opts
          end
        end
      end
    end
  end

  module AceHelpers

    ASSETS_PATH = File.expand_path('../../../assets', __FILE__).freeze
    ASSETS_EXT  = '.el-ace'.freeze
    ASSETS_REGEXP = /#{Regexp.escape ASSETS_EXT}\Z/.freeze

    ace_file = 'ace.js'
    ace_baseurl = Dir[ASSETS_PATH + '/ace-*'].find do |e|
      File.directory?(e) && File.file?(File.join(e, ace_file))
    end
    ACE_BASEURL = File.basename(ace_baseurl).freeze
    ACE_URL = File.join(ACE_BASEURL, ace_file).freeze

    TAB_SIZES  = %w[2 4].freeze
    FONT_SIZES = %w[10 12 14 16].freeze

    THEMES = Dir[File.join(ASSETS_PATH, ACE_BASEURL, 'theme-*.js')].map do |e|
      File.basename(e).gsub(/\Atheme\-|\.js\Z/, '')
    end.reject {|t| t == 'kr'}.freeze

    MODES = Dir[File.join(ASSETS_PATH, ACE_BASEURL, 'mode-*.js')].map do |e|
      File.basename(e).gsub(/\Amode\-|\.js\Z/, '')
    end.freeze

    mode_map = Hash[MODES.map {|m| '.' + m}.zip(MODES)].merge({
      '.htm'         => 'html',
      '.xhtml'       => 'html',
      '.erb'         => 'rhtml',
      '.txt'         => 'text',
      '.log'         => 'text',
      '.php4'        => 'php',
      '.phps'        => 'php',
      '.csv'         => 'text',
      '.js'          => 'javascript',
      '.asp'         => 'text',
      '.cfg'         => 'text',
      '.ini'         => 'text',
      '.py'          => 'python',
      '.pl'          => 'perl',
      '.rb'          => 'ruby',
      '.ru'          => 'ruby',
      '.gemspec'     => 'ruby',
      '.cpp'         => 'c_cpp',
      '.class'       => 'java',
      '.c'           => 'c_cpp',
      '.cgi'         => 'text',
      '.tmp'         => 'text',
      '.readme'      => 'text',
      '.changelog'   => 'text',
      '.license'     => 'text',
      '.md'          => 'markdown',
      '.yml'         => 'yaml',
      'Gemfile'      => 'ruby',
      'Rakefile'     => 'ruby',
      'license'      => 'text',
      'changelog'    => 'text',
    })
    MODE_MAP = mode_map.inject({}) do |f,(k,v)|
      f.merge(k => v, k.upcase => v)
    end.freeze
    
    def normalize_editor_id smth
      # removing non-alphanumerics as well as underscores,
      # otherwise Ace does not recognize it as a valid id.
      # also, it is important to add the digest, cause without it
      # all of "ab", "a_b", "a-b" will result in same id
      ('ELAceEditor' << Digest::MD5.hexdigest(smth.to_s) << smth.to_s).gsub(/\W|_/, '').freeze
    end

    def normalize_snippets *snippets
      snippets = snippets[0].call if snippets[0].is_a?(Proc)
      snippets.compact.flatten.map {|s| s.to_s.gsub("'", '"')}.freeze
    end

    def stringify_opts *keys
      keys.inject([]) {|a,o| (v = @opts[o]) ? a << ('%s: "%s"' % [o,v]) : a}*', '
    end
  end
end