File Coverage

lib/HTML/Object/ElementDataMap.pm
Criterion Covered Total %
statement 38 39 97.4
branch 5 8 62.5
condition 2 4 50.0
subroutine 9 9 100.0
pod 1 1 100.0
total 55 61 90.1


line stmt bran cond sub pod time code
1             ##----------------------------------------------------------------------------
2             ## HTML Object - ~/lib/HTML/Object/ElementDataMap.pm
3             ## Version v0.2.0
4             ## Copyright(c) 2021 DEGUEST Pte. Ltd.
5             ## Author: Jacques Deguest <jack@deguest.jp>
6             ## Created 2021/12/12
7             ## Modified 2022/09/18
8             ## All rights reserved
9             ##
10             ##
11             ## This program is free software; you can redistribute it and/or modify it
12             ## under the same terms as Perl itself.
13             ##----------------------------------------------------------------------------
14             package HTML::Object::ElementDataMap;
15             BEGIN
16             {
17 2     2   5424 use strict;
  2         5  
  2         62  
18 2     2   11 use warnings;
  2         3  
  2         61  
19 2     2   11 use parent qw( Module::Generic );
  2         4  
  2         10  
20 2     2   131 use vars qw( $VERSION );
  2         13  
  2         112  
21 2     2   41 our $VERSION = 'v0.2.0';
22             };
23              
24 2     2   13 use strict;
  2         3  
  2         46  
25 2     2   12 use warnings;
  2         3  
  2         807  
26              
27             sub init
28             {
29 1     1 1 91 my $self = shift( @_ );
30 1   50     4 my $elem = shift( @_ ) || return( $self->error( "No HTML::Object::Element was provided." ) );
31 1 50       5 return( $self->error( "Element object provided is not a HTML::Object::Element" ) ) if( !$self->_is_a( $elem => 'HTML::Object::Element' ) );
32 1         77 $self->{element} = $elem;
33 1         3 $self->{_init_strict_use_sub} = 1;
34 1 50       7 $self->SUPER::init( @_ ) || return( $self->pass_error );
35 1         71 return( $self );
36             }
37              
38             AUTOLOAD
39             {
40 2     2   596 my( $name ) = our $AUTOLOAD =~ /([^:]+)$/;
41 2         7 my $self = shift( @_ );
42 2   50     11 my $elem = $self->{element} || die( "No element object set!\n" );
43 2         7 ( my $copy = $name ) =~ s/^([A-Z])/\L$1\E/;
44 2         24 my $att = 'data-' . join( '-', map( lc( $_ ), split( /(?=[A-Z])/, $copy ) ) );
45 2 100       12 if( @_ )
46             {
47 1         2 my $val = shift( @_ );
48 1 50       5 if( !$elem->attributes->has( $att ) )
49             {
50 1         559 $elem->setAttribute( $att => $val );
51             }
52             else
53             {
54 0         0 $elem->attributes->set( $att => $val );
55             }
56 1         150 $elem->reset(1);
57 1         5 return( $self );
58             }
59             else
60             {
61 1         6 return( $elem->attributes->get( $att ) );
62             }
63             };
64              
65              
66             1;
67             # NOTE: POD
68             __END__
69              
70             =encoding utf-8
71              
72             =head1 NAME
73              
74             HTML::Object::ElementDataMap - HTML Object Element Data Map Class
75              
76             =head1 SYNOPSIS
77              
78             use HTML::Object::ElementDataMap;
79             my $map = HTML::Object::ElementDataMap->new( $html_element_object ) ||
80             die( HTML::Object::ElementDataMap->error, "\n" );
81             $map->dateOfBirth( '1989-12-01' );
82             # Related html element would now have an attribute data-date-of-birth set to 1989-12-01
83              
84             =head1 VERSION
85              
86             v0.2.0
87              
88             =head1 DESCRIPTION
89              
90             This module implements a L<data map|https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset> for L<HTML element|HTML::Object::Element> objects.
91              
92             It provides read/write access to custom data attributes (data-*) on L<elements|HTML::Object::Element>. It provides a map of strings with an entry for each data-* attribute.
93              
94             Those class objects are instantiated from L<HTML::Object::Element/dataset>
95              
96             =head1 Name conversion
97              
98             =head2 dash-style to camelCase conversion
99              
100             A custom data attribute name is transformed to a key for the element data entry by the following:
101              
102             =over 4
103              
104             =item 1. Lowercase all ASCII capital letters (A to Z);
105              
106             =item 2. Remove the prefix data- (including the dash);
107              
108             =item 3. For any dash (U+002D) followed by an ASCII lowercase letter a to z, remove the dash and uppercase the letter;
109              
110             =item 4. Other characters (including other dashes) are left unchanged.
111              
112             =back
113              
114             =head2 camelCase to dash-style conversion
115              
116             The opposite transformation, which maps a key to an attribute name, uses the following:
117              
118             =over 4
119              
120             =item 1. Restriction: Before transformation, a dash must not be immediately followed by an ASCII lowercase letter a to z;
121              
122             =item 2. Add the data- prefix;
123              
124             =item 3. Add a dash before any ASCII uppercase letter A to Z, then lowercase the letter;
125              
126             =item 4. Other characters are left unchanged.
127              
128             =back
129              
130             For example, a data-abc-def attribute corresponds to dataset.abcDef.
131              
132             =head1 Accessing values
133              
134             =over 4
135              
136             =item * Attributes can be set and read by the camelCase name/key as an object property of the dataset: C<$element->dataset->keyname>
137              
138             =item * Attributes can also be set and read using variable: C<$element->dataset->$keyname>
139              
140             =item * You can check if a given attribute exists like so: C<$element->attributes->exists( 'data-keyname' )>
141              
142             =back
143              
144             =head1 Setting values
145              
146             =over 4
147              
148             =item * When the attribute is set, its value is always stored as is, which means you can set reference and access them later.
149              
150             =item * To remove an attribute, you can use the L<HTML::Object::Element/removeAttribute> method: C<$element->removeAttribute( 'data-keyname' )>
151              
152             =back
153              
154             =head1 AUTHOR
155              
156             Jacques Deguest E<lt>F<jack@deguest.jp>E<gt>
157              
158             =head1 SEE ALSO
159              
160             L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset>
161              
162             =head1 COPYRIGHT & LICENSE
163              
164             Copyright(c) 2021 DEGUEST Pte. Ltd.
165              
166             All rights reserved
167              
168             This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
169              
170             =cut