@ca-plant-list/ca-plant-list 0.1.12 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/jekyll/_layouts/html.html +3 -0
- package/jekyll/assets/css/main.css +0 -4
- package/jekyll/assets/js/ui.js +10 -0
- package/lib/basepagerenderer.js +7 -7
- package/lib/families.js +19 -9
- package/lib/files.js +8 -0
- package/lib/genericpage.js +48 -0
- package/lib/html.js +23 -4
- package/lib/htmlpage.js +5 -2
- package/lib/index.d.ts +22 -2
- package/lib/pagerenderer.js +8 -8
- package/lib/pagetaxon.js +24 -28
- package/lib/taxa.js +32 -30
- package/lib/taxon.js +9 -9
- package/package.json +1 -1
- package/jekyll/_includes/plantlists.html +0 -0
- package/jekyll/index_lists.md +0 -7
package/lib/basepagerenderer.js
CHANGED
@@ -1,19 +1,19 @@
|
|
1
|
-
import * as fs from "node:fs";
|
2
1
|
import { Config } from "./config.js";
|
3
2
|
import { Families } from "./families.js";
|
3
|
+
import { Files } from "./files.js";
|
4
4
|
|
5
5
|
class BasePageRenderer {
|
6
6
|
|
7
|
-
static render( outputDir, Taxa ) {
|
7
|
+
static render( outputDir, Taxa, familyCols ) {
|
8
8
|
|
9
9
|
// Copy static files
|
10
|
-
|
10
|
+
Files.rmDir( outputDir );
|
11
11
|
// First copy default Jekyll files from package.
|
12
|
-
|
12
|
+
Files.copyDir( Config.getPackageDir() + "/jekyll", outputDir );
|
13
13
|
// Then copy Jekyll files from current dir (which may override default files).
|
14
|
-
|
14
|
+
Files.copyDir( "jekyll", outputDir );
|
15
15
|
|
16
|
-
Families.renderPages( outputDir );
|
16
|
+
Families.renderPages( outputDir, familyCols );
|
17
17
|
|
18
18
|
this.renderTools( outputDir, Taxa );
|
19
19
|
|
@@ -39,7 +39,7 @@ class BasePageRenderer {
|
|
39
39
|
names.push( row );
|
40
40
|
}
|
41
41
|
|
42
|
-
|
42
|
+
Files.write( outputDir + "/_includes/names.json", JSON.stringify( names ) );
|
43
43
|
|
44
44
|
}
|
45
45
|
|
package/lib/families.js
CHANGED
@@ -19,12 +19,12 @@ class Families {
|
|
19
19
|
}
|
20
20
|
}
|
21
21
|
|
22
|
-
static renderPages( outputDir ) {
|
22
|
+
static renderPages( outputDir, columns ) {
|
23
23
|
new PageFamilyList( Object.values( this.#families ) ).render( outputDir );
|
24
24
|
|
25
25
|
for ( const family of Object.values( this.#families ) ) {
|
26
26
|
if ( family.getTaxa() ) {
|
27
|
-
new PageFamily( family ).render( outputDir );
|
27
|
+
new PageFamily( family ).render( outputDir, columns );
|
28
28
|
}
|
29
29
|
}
|
30
30
|
}
|
@@ -48,15 +48,25 @@ class PageFamilyList extends HTMLPage {
|
|
48
48
|
|
49
49
|
html += HTML.textElement( "h1", title );
|
50
50
|
|
51
|
-
html += "<
|
51
|
+
html += "<table>";
|
52
|
+
html += "<thead>";
|
53
|
+
html += HTML.textElement( "th", "Family" );
|
54
|
+
html += HTML.textElement( "th", "Number of Species", { class: "right" } );
|
55
|
+
html += "</thead>";
|
56
|
+
|
57
|
+
html += "<tbody>";
|
52
58
|
for ( const family of this.#families ) {
|
53
59
|
const taxa = family.getTaxa();
|
54
|
-
if ( taxa ) {
|
55
|
-
|
56
|
-
html += "<li>" + link + " (" + taxa.length + ")" + "</li>";
|
60
|
+
if ( !taxa ) {
|
61
|
+
continue;
|
57
62
|
}
|
63
|
+
let cols = HTML.wrap( "td", HTML.getLink( "./" + family.getFileName(), family.getName() ) );
|
64
|
+
cols += HTML.wrap( "td", taxa.length, { class: "right" } );
|
65
|
+
html += HTML.wrap( "tr", cols );
|
58
66
|
}
|
59
|
-
html += "</
|
67
|
+
html += "</tbody>";
|
68
|
+
|
69
|
+
html += "</table>";
|
60
70
|
|
61
71
|
this.writeFile( outputDir, "list_families.html", html );
|
62
72
|
}
|
@@ -71,7 +81,7 @@ class PageFamily extends HTMLPage {
|
|
71
81
|
this.#family = family;
|
72
82
|
}
|
73
83
|
|
74
|
-
render( outputDir ) {
|
84
|
+
render( outputDir, columns ) {
|
75
85
|
|
76
86
|
let html = this.getFrontMatter( this.#family.getName() );
|
77
87
|
|
@@ -83,7 +93,7 @@ class PageFamily extends HTMLPage {
|
|
83
93
|
{ class: "section" }
|
84
94
|
);
|
85
95
|
|
86
|
-
html += Taxa.getHTMLTable( this.#family.getTaxa() );
|
96
|
+
html += Taxa.getHTMLTable( this.#family.getTaxa(), columns );
|
87
97
|
|
88
98
|
this.writeFile( outputDir, this.#family.getFileName(), html );
|
89
99
|
|
package/lib/files.js
CHANGED
@@ -3,6 +3,10 @@ import { default as unzipper } from "unzipper";
|
|
3
3
|
|
4
4
|
class Files {
|
5
5
|
|
6
|
+
static copyDir( srcDir, targetDir ) {
|
7
|
+
fs.cpSync( srcDir, targetDir, { recursive: true } );
|
8
|
+
}
|
9
|
+
|
6
10
|
static createFileFromStream( fileName, inStream ) {
|
7
11
|
|
8
12
|
function implementation( fileName, inStream, resolve ) {
|
@@ -33,6 +37,10 @@ class Files {
|
|
33
37
|
return fs.readFileSync( path, "utf8" );
|
34
38
|
}
|
35
39
|
|
40
|
+
static rmDir( dir ) {
|
41
|
+
fs.rmSync( dir, { force: true, recursive: true, maxRetries: 2, retryDelay: 1000 } );
|
42
|
+
}
|
43
|
+
|
36
44
|
static write( path, data ) {
|
37
45
|
if ( this.exists( path ) ) {
|
38
46
|
throw new Error( path + " already exists" );
|
@@ -0,0 +1,48 @@
|
|
1
|
+
import { Files, HTML, Jekyll } from "@ca-plant-list/ca-plant-list";
|
2
|
+
|
3
|
+
class GenericPage {
|
4
|
+
|
5
|
+
#outputDir;
|
6
|
+
#title;
|
7
|
+
#baseFileName;
|
8
|
+
#js;
|
9
|
+
|
10
|
+
constructor( outputDir, title, baseFileName, js ) {
|
11
|
+
this.#outputDir = outputDir;
|
12
|
+
this.#title = title;
|
13
|
+
this.#baseFileName = baseFileName;
|
14
|
+
this.#js = js;
|
15
|
+
}
|
16
|
+
|
17
|
+
getDefaultIntro() {
|
18
|
+
let html = this.#getFrontMatter();
|
19
|
+
html += HTML.textElement( "h1", this.#title );
|
20
|
+
const introPath = "lists/" + this.#baseFileName + "-intro.md";
|
21
|
+
if ( Jekyll.hasInclude( this.#outputDir, introPath ) ) {
|
22
|
+
html += HTML.wrap( "div", Jekyll.include( introPath ), { class: "section" } );
|
23
|
+
}
|
24
|
+
return html;
|
25
|
+
}
|
26
|
+
|
27
|
+
#getFrontMatter() {
|
28
|
+
return "---\n"
|
29
|
+
+ "title: \"" + this.#title + "\"\n"
|
30
|
+
+ ( this.#js ? ( "js: " + this.#js + "\n" ) : "" )
|
31
|
+
+ "---\n";
|
32
|
+
}
|
33
|
+
|
34
|
+
getOutputDir() {
|
35
|
+
return this.#outputDir;
|
36
|
+
}
|
37
|
+
|
38
|
+
getTitle() {
|
39
|
+
return this.#title;
|
40
|
+
}
|
41
|
+
|
42
|
+
writeFile( html ) {
|
43
|
+
Files.write( this.#outputDir + "/" + this.#baseFileName + ".html", html );
|
44
|
+
}
|
45
|
+
|
46
|
+
}
|
47
|
+
|
48
|
+
export { GenericPage };
|
package/lib/html.js
CHANGED
@@ -45,21 +45,40 @@ export class HTML {
|
|
45
45
|
return html;
|
46
46
|
}
|
47
47
|
|
48
|
-
|
48
|
+
/**
|
49
|
+
* Generate HTML for an <a> element.
|
50
|
+
* @param {string|undefined} href
|
51
|
+
* @param {string} linkText
|
52
|
+
* @param {Object} attributes
|
53
|
+
* @param {boolean} openInNewWindow true if the link should open in a new window.
|
54
|
+
* @returns {string} an HTML <a> element.
|
55
|
+
*/
|
56
|
+
static getLink( href, linkText, attributes = {}, openInNewWindow ) {
|
49
57
|
let html = "<a";
|
50
58
|
if ( href !== undefined ) {
|
51
59
|
html += this.renderAttribute( "href", href );
|
52
60
|
}
|
53
61
|
html += this.renderAttributes( attributes );
|
54
|
-
if (
|
62
|
+
if ( openInNewWindow ) {
|
55
63
|
html += this.renderAttribute( "target", "_blank" );
|
56
64
|
}
|
57
65
|
return html + ">" + this.escapeText( linkText ) + "</a >";
|
58
66
|
}
|
59
67
|
|
60
|
-
|
68
|
+
/**
|
69
|
+
* Get a Bootstrap formatted tooltip element.
|
70
|
+
* @param {string} text - The text or HTML that should trigger the tooltip on hover.
|
71
|
+
* @param {string} tooltip - The tooltip text or HTML.
|
72
|
+
* @param {Object} options
|
73
|
+
* @param {boolean} options.icon [true] display an icon after the text
|
74
|
+
* @returns {string} A <span> element to be used as a Bootstrap tooltip.
|
75
|
+
*/
|
76
|
+
static getToolTip( text, tooltip, options = {} ) {
|
61
77
|
const func = text.charAt( 0 ) === "<" ? HTML.wrap : HTML.textElement;
|
62
|
-
|
78
|
+
if ( options.icon !== false ) {
|
79
|
+
text += " ⓘ";
|
80
|
+
}
|
81
|
+
return func( "span", text, { "data-bs-html": "true", "title": tooltip } );
|
63
82
|
}
|
64
83
|
|
65
84
|
static renderAttribute( n, v ) {
|
package/lib/htmlpage.js
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
-
import
|
1
|
+
import { Files } from "./files.js";
|
2
2
|
|
3
|
+
/**
|
4
|
+
* @deprecated
|
5
|
+
*/
|
3
6
|
class HTMLPage {
|
4
7
|
|
5
8
|
getFrontMatter( title, js ) {
|
@@ -10,7 +13,7 @@ class HTMLPage {
|
|
10
13
|
}
|
11
14
|
|
12
15
|
writeFile( outputDir, fileName, html ) {
|
13
|
-
|
16
|
+
Files.write( outputDir + "/" + fileName, html );
|
14
17
|
}
|
15
18
|
|
16
19
|
}
|
package/lib/index.d.ts
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
export class Files {
|
2
|
+
static copyDir(srcDir: any, targetDir: any): void;
|
2
3
|
static createFileFromStream(fileName: any, inStream: any): Promise<any>;
|
3
4
|
static exists(path: any): boolean;
|
4
5
|
static fetch(url: any, targetFileName: any): Promise<void>;
|
5
6
|
static mkdir(path: any): void;
|
6
7
|
static read(path: any): string;
|
8
|
+
static rmDir(dir: any): void;
|
7
9
|
static write(path: any, data: any): void;
|
8
10
|
static zipFileExtract(zipFilePath: any, fileNameToUnzip: any, targetFilePath: any): Promise<void>;
|
9
11
|
}
|
@@ -21,8 +23,26 @@ export class HTML {
|
|
21
23
|
*/
|
22
24
|
static getElement(elName: any, text: any, attributes?: {}, options?: number): string;
|
23
25
|
static "__#2@#getElement"(elName: any, text: any, attributes: any, escape: any): string;
|
24
|
-
|
25
|
-
|
26
|
+
/**
|
27
|
+
* Generate HTML for an <a> element.
|
28
|
+
* @param {string|undefined} href
|
29
|
+
* @param {string} linkText
|
30
|
+
* @param {Object} attributes
|
31
|
+
* @param {boolean} openInNewWindow true if the link should open in a new window.
|
32
|
+
* @returns {string} an HTML <a> element.
|
33
|
+
*/
|
34
|
+
static getLink(href: string | undefined, linkText: string, attributes: any, openInNewWindow: boolean): string;
|
35
|
+
/**
|
36
|
+
* Get a Bootstrap formatted tooltip element.
|
37
|
+
* @param {string} text - The text or HTML that should trigger the tooltip on hover.
|
38
|
+
* @param {string} tooltip - The tooltip text or HTML.
|
39
|
+
* @param {Object} options
|
40
|
+
* @param {boolean} options.icon [true] display an icon after the text
|
41
|
+
* @returns {string} A <span> element to be used as a Bootstrap tooltip.
|
42
|
+
*/
|
43
|
+
static getToolTip(text: string, tooltip: string, options?: {
|
44
|
+
icon: boolean;
|
45
|
+
}): string;
|
26
46
|
static renderAttribute(n: any, v: any): string;
|
27
47
|
static renderAttributes(attributes: any): string;
|
28
48
|
static textElement(elName: any, text: any, attributes?: {}): string;
|
package/lib/pagerenderer.js
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
import * as fs from "node:fs";
|
2
1
|
import { HTML } from "./html.js";
|
3
|
-
import { Taxa,
|
2
|
+
import { Taxa, TAXA_LIST_COLS } from "./taxa.js";
|
4
3
|
import { HTMLPage } from "./htmlpage.js";
|
5
4
|
import { PageTaxon } from "./pagetaxon.js";
|
6
5
|
import { Config } from "./config.js";
|
7
6
|
import { RarePlants } from "./rareplants.js";
|
8
7
|
import { BasePageRenderer } from "./basepagerenderer.js";
|
8
|
+
import { Files } from "./files.js";
|
9
9
|
|
10
|
-
const RPI_CESA = [
|
11
|
-
const RPI_COLUMNS = [
|
10
|
+
const RPI_CESA = [ TAXA_LIST_COLS.SPECIES, TAXA_LIST_COLS.COMMON_NAME, TAXA_LIST_COLS.CESA ];
|
11
|
+
const RPI_COLUMNS = [ TAXA_LIST_COLS.SPECIES_BARE, TAXA_LIST_COLS.COMMON_NAME, TAXA_LIST_COLS.CNPS_RANK ];
|
12
12
|
|
13
13
|
class PageRenderer extends BasePageRenderer {
|
14
14
|
|
@@ -20,7 +20,7 @@ class PageRenderer extends BasePageRenderer {
|
|
20
20
|
|
21
21
|
const taxa = Taxa.getTaxa();
|
22
22
|
for ( const taxon of taxa ) {
|
23
|
-
new PageTaxon( taxon ).render(
|
23
|
+
new PageTaxon( outputDir, taxon ).render();
|
24
24
|
}
|
25
25
|
|
26
26
|
}
|
@@ -46,8 +46,8 @@ class PageRenderer extends BasePageRenderer {
|
|
46
46
|
continue;
|
47
47
|
}
|
48
48
|
|
49
|
-
|
50
|
-
|
49
|
+
Files.write( outputDir + "/calflora_" + list.filename + ".txt", calfloraTaxa.join( "\n" ) );
|
50
|
+
Files.write( outputDir + "/inat_" + list.filename + ".txt", iNatTaxa.join( "\n" ) );
|
51
51
|
|
52
52
|
const cols = columns ? columns : list.columns;
|
53
53
|
new PageTaxonList().render( outputDir, taxa, list.filename, list.name, cols );
|
@@ -170,7 +170,7 @@ class PageRenderer extends BasePageRenderer {
|
|
170
170
|
html += "</div>";
|
171
171
|
|
172
172
|
// Write lists to includes directory so it can be inserted into pages.
|
173
|
-
|
173
|
+
Files.write( outputDir + "/_includes/plantlists.html", html );
|
174
174
|
|
175
175
|
}
|
176
176
|
|
package/lib/pagetaxon.js
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
-
import
|
2
|
-
import { HTML, HTML_OPTIONS } from "./html.js";
|
1
|
+
import { HTML } from "./html.js";
|
3
2
|
import { Jepson } from "./jepson.js";
|
4
|
-
import { HTMLPage } from "./htmlpage.js";
|
5
3
|
import { Config } from "./config.js";
|
6
4
|
import { RarePlants } from "./rareplants.js";
|
5
|
+
import { GenericPage } from "./genericpage.js";
|
6
|
+
import { Files } from "./files.js";
|
7
7
|
|
8
|
-
class PageTaxon extends
|
8
|
+
class PageTaxon extends GenericPage {
|
9
9
|
|
10
10
|
#taxon;
|
11
11
|
|
12
|
-
constructor( taxon ) {
|
13
|
-
super();
|
12
|
+
constructor( outputDir, taxon ) {
|
13
|
+
super( outputDir, taxon.getName(), taxon.getBaseFileName() );
|
14
14
|
this.#taxon = taxon;
|
15
15
|
}
|
16
16
|
|
@@ -44,7 +44,7 @@ class PageTaxon extends HTMLPage {
|
|
44
44
|
+ this.#taxon.getCalfloraName().replaceAll( " ", "+" ),
|
45
45
|
"Calflora",
|
46
46
|
{},
|
47
|
-
|
47
|
+
true
|
48
48
|
)
|
49
49
|
);
|
50
50
|
const iNatID = this.#taxon.getINatID();
|
@@ -55,7 +55,7 @@ class PageTaxon extends HTMLPage {
|
|
55
55
|
+ "&quality_grade=research&subview=map&taxon_id=" + iNatID,
|
56
56
|
"iNaturalist",
|
57
57
|
{},
|
58
|
-
|
58
|
+
true
|
59
59
|
)
|
60
60
|
);
|
61
61
|
}
|
@@ -67,7 +67,7 @@ class PageTaxon extends HTMLPage {
|
|
67
67
|
let html = "";
|
68
68
|
if ( list.length > 0 ) {
|
69
69
|
html += "<div class=\"section " + className + "\">";
|
70
|
-
html += HTML.
|
70
|
+
html += HTML.textElement( "h2", header );
|
71
71
|
html += "<ul>";
|
72
72
|
html += HTML.arrayToLI( list );
|
73
73
|
html += "</ul>";
|
@@ -83,17 +83,16 @@ class PageTaxon extends HTMLPage {
|
|
83
83
|
}
|
84
84
|
const ranks = [];
|
85
85
|
|
86
|
-
ranks.push( HTML.
|
87
|
-
+ HTML.
|
86
|
+
ranks.push( HTML.textElement( "span", "CNPS Rare Plant Rank:", { class: "label" } )
|
87
|
+
+ HTML.getToolTip( cnpsRank, this.#taxon.getRPIRankAndThreatTooltip() ) );
|
88
88
|
if ( this.#taxon.getCESA() ) {
|
89
|
-
ranks.push( HTML.
|
89
|
+
ranks.push( HTML.textElement( "span", "CESA:", { class: "label" } ) + RarePlants.getCESADescription( this.#taxon.getCESA() ) );
|
90
90
|
}
|
91
91
|
|
92
|
-
return HTML.
|
92
|
+
return HTML.wrap(
|
93
93
|
"div",
|
94
94
|
"<ul>" + HTML.arrayToLI( ranks ) + "</ul>",
|
95
|
-
{ class: "section" }
|
96
|
-
HTML_OPTIONS.NO_ESCAPE
|
95
|
+
{ class: "section" }
|
97
96
|
);
|
98
97
|
}
|
99
98
|
|
@@ -115,27 +114,24 @@ class PageTaxon extends HTMLPage {
|
|
115
114
|
return this.#taxon.getSynonyms();
|
116
115
|
}
|
117
116
|
|
118
|
-
render(
|
117
|
+
render() {
|
119
118
|
|
120
|
-
let html = this.
|
121
|
-
|
122
|
-
html += HTML.getElement( "h1", this.#taxon.getName() );
|
119
|
+
let html = this.getDefaultIntro();
|
123
120
|
|
124
121
|
html += "<div class=\"wrapper\">";
|
125
122
|
|
126
123
|
const cn = this.#taxon.getCommonNames();
|
127
124
|
if ( cn.length > 0 ) {
|
128
|
-
html += HTML.
|
125
|
+
html += HTML.textElement( "div", cn.join( ", " ), { class: "section common-names" } );
|
129
126
|
}
|
130
127
|
|
131
|
-
html += HTML.
|
128
|
+
html += HTML.textElement( "div", this.#taxon.getStatusDescription(), { class: "section native-status" } );
|
132
129
|
|
133
130
|
const family = this.#taxon.getFamily();
|
134
|
-
html += HTML.
|
131
|
+
html += HTML.wrap(
|
135
132
|
"div",
|
136
|
-
HTML.
|
137
|
-
{ class: "section" }
|
138
|
-
HTML_OPTIONS.NO_ESCAPE
|
133
|
+
HTML.textElement( "span", "Family:", { class: "label" } ) + HTML.getLink( "./" + family.getFileName(), family.getName() ),
|
134
|
+
{ class: "section" }
|
139
135
|
);
|
140
136
|
|
141
137
|
html += this.#getRarityInfo();
|
@@ -143,8 +139,8 @@ class PageTaxon extends HTMLPage {
|
|
143
139
|
html += "</div>";
|
144
140
|
|
145
141
|
const introName = "intros/" + this.#taxon.getFileName( "md" );
|
146
|
-
if (
|
147
|
-
html += HTML.
|
142
|
+
if ( Files.exists( "./jekyll/_includes/" + introName ) ) {
|
143
|
+
html += HTML.wrap(
|
148
144
|
"div",
|
149
145
|
"{% capture my_include %}{% include " + introName + "%}{% endcapture %}{{ my_include | markdownify }}",
|
150
146
|
{ class: "section" }
|
@@ -158,7 +154,7 @@ class PageTaxon extends HTMLPage {
|
|
158
154
|
html += this.#getListSectionHTML( this.#getSynonyms(), "Synonyms", "synonyms" );
|
159
155
|
html += "</div>";
|
160
156
|
|
161
|
-
this.writeFile(
|
157
|
+
this.writeFile( html );
|
162
158
|
|
163
159
|
}
|
164
160
|
|
package/lib/taxa.js
CHANGED
@@ -4,14 +4,30 @@ import { HTML } from "./html.js";
|
|
4
4
|
import { CSV } from "./csv.js";
|
5
5
|
import { RarePlants } from "./rareplants.js";
|
6
6
|
|
7
|
-
const
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
const TAXA_LIST_COLS = {
|
8
|
+
CESA: {
|
9
|
+
title: "CESA",
|
10
|
+
data: ( t ) => RarePlants.getCESADescription( t.getCESA() )
|
11
|
+
},
|
12
|
+
COMMON_NAME: {
|
13
|
+
title: "Common Name",
|
14
|
+
data: ( t ) => t.getCommonNames().join( ", " )
|
15
|
+
},
|
16
|
+
CNPS_RANK: {
|
17
|
+
title: "CNPS Rank",
|
18
|
+
data: ( t ) => HTML.getToolTip( HTML.textElement( "span", t.getRPIRankAndThreat() ), t.getRPIRankAndThreatTooltip() )
|
19
|
+
},
|
20
|
+
SPECIES: {
|
21
|
+
title: "Species",
|
22
|
+
data: ( t ) => t.getHTMLLink( true, true )
|
23
|
+
},
|
24
|
+
SPECIES_BARE: {
|
25
|
+
title: "Species",
|
26
|
+
data: ( t ) => t.getHTMLLink( true, false )
|
27
|
+
},
|
12
28
|
};
|
13
29
|
|
14
|
-
const DEFAULT_COLUMNS = [
|
30
|
+
const DEFAULT_COLUMNS = [ TAXA_LIST_COLS.SPECIES, TAXA_LIST_COLS.COMMON_NAME ];
|
15
31
|
|
16
32
|
class Taxa {
|
17
33
|
|
@@ -20,36 +36,22 @@ class Taxa {
|
|
20
36
|
|
21
37
|
static getHTMLTable( taxa, columns = DEFAULT_COLUMNS ) {
|
22
38
|
|
23
|
-
let includeRPI = true;
|
24
|
-
|
25
39
|
let html = "<table><thead>";
|
26
|
-
for ( const
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
includeRPI = false;
|
31
|
-
}
|
40
|
+
for ( const col of columns ) {
|
41
|
+
const className = col.class;
|
42
|
+
const atts = className ? { class: className } : {};
|
43
|
+
html += HTML.textElement( "th", col.title, atts );
|
32
44
|
}
|
33
45
|
html += "</thead>";
|
34
46
|
html += "<tbody>";
|
35
47
|
|
36
48
|
for ( const taxon of taxa ) {
|
37
49
|
html += "<tr>";
|
38
|
-
for ( const
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
case COLUMNS.COL_COMMON_NAME:
|
44
|
-
html += HTML.textElement( "td", taxon.getCommonNames().join( ", " ) );
|
45
|
-
break;
|
46
|
-
case COLUMNS.COL_CNPS_RANK:
|
47
|
-
html += HTML.wrap( "td", HTML.wrap( "span", taxon.getRPIRankAndThreat(), taxon.getRPIRankAndThreatTooltip( {} ) ) );
|
48
|
-
break;
|
49
|
-
case COLUMNS.COL_SPECIES:
|
50
|
-
html += HTML.wrap( "td", taxon.getHTMLLink( true, includeRPI ) );
|
51
|
-
break;
|
52
|
-
}
|
50
|
+
for ( const col of columns ) {
|
51
|
+
const data = col.data( taxon );
|
52
|
+
const className = col.class;
|
53
|
+
const atts = className ? { class: className } : {};
|
54
|
+
html += HTML.wrap( "td", data, atts );
|
53
55
|
}
|
54
56
|
html += "</tr>";
|
55
57
|
}
|
@@ -120,4 +122,4 @@ class Taxa {
|
|
120
122
|
|
121
123
|
}
|
122
124
|
|
123
|
-
export { Taxa,
|
125
|
+
export { Taxa, TAXA_LIST_COLS };
|
package/lib/taxon.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import { Config } from "./config.js";
|
2
2
|
import { Genera } from "./genera.js";
|
3
|
-
import { HTML
|
3
|
+
import { HTML } from "./html.js";
|
4
4
|
import { RarePlants } from "./rareplants.js";
|
5
5
|
|
6
6
|
class Taxon {
|
@@ -72,7 +72,7 @@ class Taxon {
|
|
72
72
|
"https://www.calflora.org/app/taxon?crn=" + calfloraID,
|
73
73
|
"Calflora",
|
74
74
|
{},
|
75
|
-
|
75
|
+
true
|
76
76
|
);
|
77
77
|
}
|
78
78
|
|
@@ -107,10 +107,11 @@ class Taxon {
|
|
107
107
|
className = "rare";
|
108
108
|
}
|
109
109
|
const attributes = { class: className };
|
110
|
+
const link = HTML.wrap( "span", HTML.getLink( href, this.getName() ), attributes );
|
110
111
|
if ( className === "rare" ) {
|
111
|
-
this.getRPIRankAndThreatTooltip(
|
112
|
+
return HTML.getToolTip( link, this.getRPIRankAndThreatTooltip(), { icon: false } );
|
112
113
|
}
|
113
|
-
return
|
114
|
+
return link;
|
114
115
|
}
|
115
116
|
|
116
117
|
getINatID() {
|
@@ -127,7 +128,7 @@ class Taxon {
|
|
127
128
|
if ( !iNatID ) {
|
128
129
|
return "";
|
129
130
|
}
|
130
|
-
const link = HTML.getLink( "https://www.inaturalist.org/taxa/" + iNatID, "iNaturalist", {},
|
131
|
+
const link = HTML.getLink( "https://www.inaturalist.org/taxa/" + iNatID, "iNaturalist", {}, true );
|
131
132
|
return this.#iNatSyn ? ( link + " (" + this.#iNatSyn + ")" ) : link;
|
132
133
|
}
|
133
134
|
|
@@ -154,9 +155,8 @@ class Taxon {
|
|
154
155
|
return this.#rankRPI;
|
155
156
|
}
|
156
157
|
|
157
|
-
getRPIRankAndThreatTooltip(
|
158
|
-
|
159
|
-
return attributes;
|
158
|
+
getRPIRankAndThreatTooltip() {
|
159
|
+
return RarePlants.getRPIRankAndThreatDescriptions( this.getRPIRankAndThreat() ).join( "<br>" );
|
160
160
|
}
|
161
161
|
|
162
162
|
getRPITaxonLink() {
|
@@ -164,7 +164,7 @@ class Taxon {
|
|
164
164
|
if ( !rpiID ) {
|
165
165
|
return "";
|
166
166
|
}
|
167
|
-
const link = HTML.getLink( "https://rareplants.cnps.org/Plants/Details/" + rpiID, "CNPS Rare Plant Inventory", {},
|
167
|
+
const link = HTML.getLink( "https://rareplants.cnps.org/Plants/Details/" + rpiID, "CNPS Rare Plant Inventory", {}, true );
|
168
168
|
return link;
|
169
169
|
}
|
170
170
|
|
package/package.json
CHANGED
File without changes
|