Skip to content

Commit

Permalink
Merge pull request #2373 from tvdeyen/add-dom-id-class
Browse files Browse the repository at this point in the history
Add a element DOM id class
  • Loading branch information
tvdeyen authored Sep 7, 2022
2 parents db7c37f + b78ed37 commit be7a642
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 17 deletions.
12 changes: 12 additions & 0 deletions app/models/alchemy/element.rb
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,18 @@ def new(attributes = {})
super(element_definition.merge(element_attributes).except(*FORBIDDEN_DEFINITION_ATTRIBUTES))
end

# The class responsible for the +dom_id+ of elements.
# Defaults to +Alchemy::Element::DomId+.
def dom_id_class
@_dom_id_class || DomId
end

# Register a custom +DomId+ class responsible for the +dom_id+ of elements.
# Defaults to +Alchemy::Element::DomId+.
def dom_id_class=(klass)
@_dom_id_class = klass
end

# This methods does a copy of source and all depending contents and all of their depending essences.
#
# == Options
Expand Down
30 changes: 30 additions & 0 deletions app/models/alchemy/element/dom_id.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true

module Alchemy
# Returns a dom id used for elements html id tag.
#
# Uses the elements name and its position on the page.
# If the element is nested in a parent element it prefixes
# the id with the parent elements dom_id.
#
# Register your own dom id class with
#
# Alchemy::Element.dom_id_class = MyDomIdClass
#
class Element < BaseRecord
class DomId
def initialize(element)
@element = element
@parent_element = element.parent_element
end

def call
[parent_element&.dom_id, element.name, element.position].compact.join("-")
end

private

attr_reader :element, :parent_element
end
end
end
2 changes: 1 addition & 1 deletion app/models/alchemy/element/presenters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def display_name_with_preview_text(maxlength = 30)
# Returns a dom id used for elements html id tag.
#
def dom_id
[parent_element&.dom_id, name, position].compact.join("-")
self.class.dom_id_class.new(self).call
end

# The content that's used for element's preview text.
Expand Down
31 changes: 31 additions & 0 deletions spec/models/alchemy/element/dom_id_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# frozen_string_literal: true

require "rails_helper"

RSpec.describe Alchemy::Element::DomId do
describe "#call" do
subject(:dom_id) do
described_class.new(element).call
end

let(:element) { build_stubbed(:alchemy_element, position: 1) }

it "returns a string from element name and position" do
expect(dom_id).to eq("#{element.name}-#{element.position}")
end

context "with a parent element" do
let(:parent_element) do
build_stubbed(:alchemy_element, position: 1)
end

let(:element) do
build_stubbed(:alchemy_element, position: 1, parent_element: parent_element)
end

it "returns a string from element name and position" do
expect(dom_id).to eq("#{parent_element.name}-#{parent_element.position}-#{element.name}-#{element.position}")
end
end
end
end
40 changes: 24 additions & 16 deletions spec/models/alchemy/element_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,27 @@ module Alchemy
end
end

describe ".dom_id_class" do
it "defaults to Alchemy::Element::DomId" do
expect(described_class.dom_id_class).to eq(Alchemy::Element::DomId)
end
end

describe ".dom_id_class=" do
let(:dummy_dom_id) { Class.new }

around do |example|
default_class = described_class.dom_id_class
described_class.dom_id_class = dummy_dom_id
example.run
described_class.dom_id_class = default_class
end

it "sets the dom id class" do
expect(described_class.dom_id_class).to eq(dummy_dom_id)
end
end

describe ".copy" do
subject { Element.copy(element) }

Expand Down Expand Up @@ -543,22 +564,9 @@ module Alchemy
describe "#dom_id" do
let(:element) { build_stubbed(:alchemy_element, position: 1) }

it "returns a string from element name and position" do
expect(element.dom_id).to eq("#{element.name}-#{element.position}")
end

context "with a parent element" do
let(:parent_element) do
build_stubbed(:alchemy_element, position: 1)
end

let(:element) do
build_stubbed(:alchemy_element, position: 1, parent_element: parent_element)
end

it "returns a string from element name and position" do
expect(element.dom_id).to eq("#{parent_element.name}-#{parent_element.position}-#{element.name}-#{element.position}")
end
it "calls dom id class" do
expect(Alchemy::Element.dom_id_class).to receive(:new).with(element).and_call_original
element.dom_id
end
end

Expand Down

0 comments on commit be7a642

Please sign in to comment.