# Frozen-string-literal: true # Copyright: 2012 - 2018 - MIT License # Encoding: utf-8 module Jekyll module Assets class Hook class UnknownHookError < RuntimeError def initialize(point) super "Unknown hook point `#{point}'" end end # -- class Point attr_accessor :block, :priority # -- # A hook point only holds data for later, it # really serves no other purpose for now, other # than to make live easier for handling hooks # and their sorting, later in stream. # -- def initialize(priority, &block) @priority, @block = priority, block end end # -- class << self attr_reader :points end # -- @points = { env: { before_init: [], after_init: [], after_write: [], }, config: { before_merge: [], }, asset: { before_compile: [], before_read: [], after_read: [], after_compression: [], before_write: [], after_write: [], }, liquid: { before_render: [], }, } # -- # Create a hook point to attach hooks to. # @param [Array] point the parent and child. # @note plugins can create their own points if wished. # @return [Hash>] # -- def self.add_point(*point) raise ArgumentError, "only give 2 points" if point.count > 2 @points[point[0]] ||= {} @points[point[0]][point[1]] ||= {} @points end # -- # @return [Array] # @param [Array] point the parent and child. # @note this is really internal. # Get a hook point. # -- def self.get_point(*point) check_point(*point) @points[point[0]][point[1]] .sort_by(&:priority) end # -- # Trigger a hook point. # @note plugins can trigger their own hooks. # @param [Array] point the parent and child. # @param [Proc{}] block the code to run. # @see self.add_point # @return [nil] # -- def self.trigger(*point, &block) hooks = get_point(*point) Logger.debug "messaging hooks on #{point.last} " \ "through #{point.first}" hooks.map do |v| block.call(v.block) end end # -- # Register a hook on a hook point. # @param [Array] point the parent and child. # @param [Integer] priority your priority. # @note this is what plugins should use. # @return [nil] # -- def self.register(*point, priority: 48, &block) check_point(*point) point_ = Point.new(priority, &block) out = @points[point[0]] out = out[point[1]] out << point_ end # -- # @param point the points to check. # Checks that a point exists or raises an error. # @return [nil] # -- def self.check_point(*point) raise ArgumentError, "only give 2 points" if point.count > 2 if !@points.key?(point[0]) || !@points[point[0]].key?(point[1]) raise ArgumentError, "Unknown hook #{point}" end end end end end