diff --git a/class/dashboard/subpage-main.php b/class/dashboard/subpage-main.php index 9e5092a..13d74c4 100644 --- a/class/dashboard/subpage-main.php +++ b/class/dashboard/subpage-main.php @@ -28,8 +28,16 @@ * @see * @since 2.2.10 reference container row border option, thanks to @noobishh 2020-12-25T2316+0100 * @see + * @since 2.3.0 Reference container: convert top padding to margin and make it a setting, thanks to @hamshe + * @see + * @since 2.3.0 rename Priority level tab as Scope and priority 2020-12-26T2222+0100 + * @since 2.3.0 swap Custom CSS migration Boolean from 'migration complete' to 'show legacy' 2020-12-27T1243+0100 + * @since 2.3.0 mention op. cit. abbreviation 2020-12-28T2342+0100 + * @since 2.3.0 add settings for hard links, thanks to @psykonevro and @martinneumannat 2020-12-29T1322+0100 + * @see + * @see * - * Last modified: 2020-12-25T2336+0100 + * Last modified: 2020-12-31T0801+0100 */ /** @@ -90,8 +98,9 @@ class MCI_Footnotes_Layout_Settings extends MCI_Footnotes_LayoutEngine { protected function getSections() { $l_arr_Tabs = array(); $l_arr_Tabs[] = $this->addSection("settings", __("General settings", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), 0, true); + // tab name used in public function CustomCSSMigration() $l_arr_Tabs[] = $this->addSection("customize", __("Referrers and tooltips", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), 1, true); - $l_arr_Tabs[] = $this->addSection("expert", __("Priority level", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), 2, true); + $l_arr_Tabs[] = $this->addSection("expert", __("Scope and priority", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), 2, true); $l_arr_Tabs[] = $this->addSection("customcss", __("Custom CSS", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), 3, true); $l_arr_Tabs[] = $this->addSection("how-to", __("Quick start guide", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), null, false); return $l_arr_Tabs; @@ -137,13 +146,13 @@ class MCI_Footnotes_Layout_Settings extends MCI_Footnotes_LayoutEngine { $l_arr_MetaBoxes[] = $this->addMetaBox("customize", "mouse-over-box-timing", __("Tooltip timing", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), "MouseOverBoxTiming"); $l_arr_MetaBoxes[] = $this->addMetaBox("customize", "mouse-over-box-truncation", __("Tooltip truncation", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), "MouseOverBoxTruncation"); $l_arr_MetaBoxes[] = $this->addMetaBox("customize", "mouse-over-box-appearance", __("Tooltip appearance", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), "MouseOverBoxAppearance"); - if (!MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_CUSTOM_CSS_MIGRATED))) { + if (MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_CUSTOM_CSS_LEGACY_ENABLE))) { $l_arr_MetaBoxes[] = $this->addMetaBox("customize", "custom-css", __("Your existing Custom CSS code", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), "CustomCSS"); } $l_arr_MetaBoxes[] = $this->addMetaBox("expert", "lookup", __("WordPress hooks with priority level", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), "LookupHooks"); - if (!MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_CUSTOM_CSS_MIGRATED))) { + if (MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_CUSTOM_CSS_LEGACY_ENABLE))) { $l_arr_MetaBoxes[] = $this->addMetaBox("customcss", "custom-css-migration", __("Your existing Custom CSS code", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), "CustomCSSMigration"); } $l_arr_MetaBoxes[] = $this->addMetaBox("customcss", "custom-css-new", __("Custom CSS", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), "CustomCSSNew"); @@ -234,9 +243,6 @@ class MCI_Footnotes_Layout_Settings extends MCI_Footnotes_LayoutEngine { "label-border" => $this->addLabel(MCI_Footnotes_Settings::C_BOOL_REFERENCE_CONTAINER_LABEL_BOTTOM_BORDER, __("Border under the heading:", MCI_Footnotes_Config::C_STR_PLUGIN_NAME)), "border" => $this->addSelectBox(MCI_Footnotes_Settings::C_BOOL_REFERENCE_CONTAINER_LABEL_BOTTOM_BORDER, $l_arr_Enabled), - "label-row-borders" => $this->addLabel(MCI_Footnotes_Settings::C_BOOL_REFERENCE_CONTAINER_ROW_BORDERS_ENABLE, __("Borders around the table rows:", MCI_Footnotes_Config::C_STR_PLUGIN_NAME)), - "row-borders" => $this->addSelectBox(MCI_Footnotes_Settings::C_BOOL_REFERENCE_CONTAINER_ROW_BORDERS_ENABLE, $l_arr_Enabled), - "label-collapse" => $this->addLabel(MCI_Footnotes_Settings::C_BOOL_REFERENCE_CONTAINER_COLLAPSE, __("Collapse by default:", MCI_Footnotes_Config::C_STR_PLUGIN_NAME)), "collapse" => $this->addSelectBox(MCI_Footnotes_Settings::C_BOOL_REFERENCE_CONTAINER_COLLAPSE, $l_arr_Enabled), @@ -248,6 +254,17 @@ class MCI_Footnotes_Layout_Settings extends MCI_Footnotes_LayoutEngine { "shortcode" => $this->addTextBox(MCI_Footnotes_Settings::C_STR_REFERENCE_CONTAINER_POSITION_SHORTCODE), "notice-shortcode" => __("If present in the content, any shortcode in this text box will be replaced with the reference container.", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), + "label-startpage" => $this->addLabel(MCI_Footnotes_Settings::C_BOOL_REFERENCE_CONTAINER_START_PAGE_ENABLE, __("Display on start page too:", MCI_Footnotes_Config::C_STR_PLUGIN_NAME)), + "startpage" => $this->addSelectBox(MCI_Footnotes_Settings::C_BOOL_REFERENCE_CONTAINER_START_PAGE_ENABLE, $l_arr_Enabled), + + "label-margin-top" => $this->addLabel(MCI_Footnotes_Settings::C_INT_REFERENCE_CONTAINER_TOP_MARGIN, __("Top margin:", MCI_Footnotes_Config::C_STR_PLUGIN_NAME)), + "margin-top" => $this->addNumBox(MCI_Footnotes_Settings::C_INT_REFERENCE_CONTAINER_TOP_MARGIN, -500, 500), + "notice-margin-top" => __("pixels; may be negative", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), + + "label-margin-bottom" => $this->addLabel(MCI_Footnotes_Settings::C_INT_REFERENCE_CONTAINER_BOTTOM_MARGIN, __("Bottom margin:", MCI_Footnotes_Config::C_STR_PLUGIN_NAME)), + "margin-bottom" => $this->addNumBox(MCI_Footnotes_Settings::C_INT_REFERENCE_CONTAINER_BOTTOM_MARGIN, -500, 500), + "notice-margin-bottom" => __("pixels; may be negative", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), + "label-page-layout" => $this->addLabel(MCI_Footnotes_Settings::C_STR_FOOTNOTES_PAGE_LAYOUT_SUPPORT, __("Apply basic responsive page layout:", MCI_Footnotes_Config::C_STR_PLUGIN_NAME)), "page-layout" => $this->addSelectBox(MCI_Footnotes_Settings::C_STR_FOOTNOTES_PAGE_LAYOUT_SUPPORT, $l_arr_PageLayoutOptions), "notice-page-layout" => __("Most themes don’t need this fix.", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), @@ -256,9 +273,6 @@ class MCI_Footnotes_Layout_Settings extends MCI_Footnotes_LayoutEngine { "url-wrap" => $this->addSelectBox(MCI_Footnotes_Settings::C_BOOL_FOOTNOTE_URL_WRAP_ENABLED, $l_arr_Enabled), "notice-url-wrap" => __("Unicode-conformant browsers don’t need this fix.", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), - "label-startpage" => $this->addLabel(MCI_Footnotes_Settings::C_BOOL_REFERENCE_CONTAINER_START_PAGE_ENABLE, __("Display on start page too:", MCI_Footnotes_Config::C_STR_PLUGIN_NAME)), - "startpage" => $this->addSelectBox(MCI_Footnotes_Settings::C_BOOL_REFERENCE_CONTAINER_START_PAGE_ENABLE, $l_arr_Enabled), - "label-symbol" => $this->addLabel(MCI_Footnotes_Settings::C_BOOL_REFERENCE_CONTAINER_BACKLINK_SYMBOL_ENABLE, __("Display a backlink symbol:", MCI_Footnotes_Config::C_STR_PLUGIN_NAME)), "symbol-enable" => $this->addSelectBox(MCI_Footnotes_Settings::C_BOOL_REFERENCE_CONTAINER_BACKLINK_SYMBOL_ENABLE, $l_arr_Enabled), "notice-symbol" => __("Please choose or input the symbol at the top of the next dashboard tab.", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), @@ -270,6 +284,9 @@ class MCI_Footnotes_Layout_Settings extends MCI_Footnotes_LayoutEngine { "3column" => $this->addSelectBox(MCI_Footnotes_Settings::C_BOOL_REFERENCE_CONTAINER_3COLUMN_LAYOUT_ENABLE, $l_arr_Enabled), "notice-3column" => __("This legacy layout is available if identical footnotes are not combined.", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), + "label-row-borders" => $this->addLabel(MCI_Footnotes_Settings::C_BOOL_REFERENCE_CONTAINER_ROW_BORDERS_ENABLE, __("Borders around the table rows:", MCI_Footnotes_Config::C_STR_PLUGIN_NAME)), + "row-borders" => $this->addSelectBox(MCI_Footnotes_Settings::C_BOOL_REFERENCE_CONTAINER_ROW_BORDERS_ENABLE, $l_arr_Enabled), + "label-separator" => $this->addLabel(MCI_Footnotes_Settings::C_BOOL_BACKLINKS_SEPARATOR_ENABLED, __("Add a separator when enumerating backlinks:", MCI_Footnotes_Config::C_STR_PLUGIN_NAME)), "separator-enable" => $this->addSelectBox(MCI_Footnotes_Settings::C_BOOL_BACKLINKS_SEPARATOR_ENABLED, $l_arr_Enabled), "separator-options" => $this->addSelectBox(MCI_Footnotes_Settings::C_STR_BACKLINKS_SEPARATOR_OPTION, $l_arr_Separators), @@ -411,7 +428,7 @@ class MCI_Footnotes_Layout_Settings extends MCI_Footnotes_LayoutEngine { "identical" => $this->addSelectBox(MCI_Footnotes_Settings::C_BOOL_COMBINE_IDENTICAL_FOOTNOTES, $l_arr_Enable), "notice-identical" => __("This option may require copy-pasting footnotes in multiple instances.", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), // Support for Ibid. notation added thanks to @meglio in . - "description-identical" => __("Even when footnotes are combined, footnote numbers keep incrementing. This avoids suboptimal referrer and backlink disambiguation using a secondary numbering system. The Ibid. notation followed by the current page number avoids repeating the footnote content. For changing sources, shortened citations may be used. Repeating full citations is also an opportunity to add details.", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), + "description-identical" => __("Even when footnotes are combined, footnote numbers keep incrementing. This avoids suboptimal referrer and backlink disambiguation using a secondary numbering system. The Ibid. notation and the op. cit. abbreviation followed by the current page number avoid repeating the footnote content. For changing sources, shortened citations may be used. Repeating full citations is also an opportunity to add details.", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), ) ); // display template with replaced placeholders @@ -420,6 +437,12 @@ class MCI_Footnotes_Layout_Settings extends MCI_Footnotes_LayoutEngine { public function Scrolling() { + // options for enabling hard links for AMP compat: + $l_arr_Enable = array( + "yes" => __("Yes", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), + "no" => __("No", MCI_Footnotes_Config::C_STR_PLUGIN_NAME) + ); + // load template file $l_obj_Template = new MCI_Footnotes_Template(MCI_Footnotes_Template::C_STR_DASHBOARD, "settings-scrolling"); // replace all placeholders @@ -432,7 +455,24 @@ class MCI_Footnotes_Layout_Settings extends MCI_Footnotes_LayoutEngine { "label-scroll-duration" => $this->addLabel(MCI_Footnotes_Settings::C_INT_FOOTNOTES_SCROLL_DURATION, __("Scroll duration:", MCI_Footnotes_Config::C_STR_PLUGIN_NAME)), "scroll-duration" => $this->addNumBox(MCI_Footnotes_Settings::C_INT_FOOTNOTES_SCROLL_DURATION, 0, 20000), - "notice-scroll-duration" => __("milliseconds", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), + "notice-scroll-duration" => __("milliseconds; instantly if hard links are enabled and JavaScript is disabled", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), + + // enable hard links for AMP compat: + "label-hard-links" => $this->addLabel(MCI_Footnotes_Settings::C_BOOL_FOOTNOTES_HARD_LINKS_ENABLE, __("Enable hard links:", MCI_Footnotes_Config::C_STR_PLUGIN_NAME)), + "hard-links" => $this->addSelectBox(MCI_Footnotes_Settings::C_BOOL_FOOTNOTES_HARD_LINKS_ENABLE, $l_arr_Enable), + "notice-hard-links" => __("Hard links are indispensable for AMP compatibility and allow to link to footnotes.", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), + + "label-footnote" => $this->addLabel(MCI_Footnotes_Settings::C_STR_FOOTNOTE_FRAGMENT_ID_SLUG, __("Fragment identifier slug for footnotes:", MCI_Footnotes_Config::C_STR_PLUGIN_NAME)), + "footnote" => $this->addTextBox(MCI_Footnotes_Settings::C_STR_FOOTNOTE_FRAGMENT_ID_SLUG), + "notice-footnote" => __("This will show up in the address bar after clicking on a hard-linked footnote referrer.", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), + + "label-referrer" => $this->addLabel(MCI_Footnotes_Settings::C_STR_REFERRER_FRAGMENT_ID_SLUG, __("Fragment identifier slug for footnote referrers:", MCI_Footnotes_Config::C_STR_PLUGIN_NAME)), + "referrer" => $this->addTextBox(MCI_Footnotes_Settings::C_STR_REFERRER_FRAGMENT_ID_SLUG), + "notice-referrer" => __("This will show up in the address bar after clicking on a hard-linked backlink.", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), + + "label-separator" => $this->addLabel(MCI_Footnotes_Settings::C_STR_HARD_LINK_IDS_SEPARATOR, __("ID separator:", MCI_Footnotes_Config::C_STR_PLUGIN_NAME)), + "separator" => $this->addTextBox(MCI_Footnotes_Settings::C_STR_HARD_LINK_IDS_SEPARATOR), + "notice-separator" => __("May be empty or any string, for example _, - or +, to distinguish post number, container number and footnote number.", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), ) ); @@ -788,6 +828,7 @@ class MCI_Footnotes_Layout_Settings extends MCI_Footnotes_LayoutEngine { * of the footnote number. * * @since 2.1.4 moved to Settings > Reference container > Display a backlink symbol + * @since 2.2.1 and 2.2.4 back here */ public function HyperlinkArrow() { // load template file @@ -795,7 +836,7 @@ class MCI_Footnotes_Layout_Settings extends MCI_Footnotes_LayoutEngine { // replace all placeholders $l_obj_Template->replace( array( - "label-symbol" => $this->addLabel(MCI_Footnotes_Settings::C_STR_HYPERLINK_ARROW, __("Select the backlink symbol:", MCI_Footnotes_Config::C_STR_PLUGIN_NAME)), + "label-symbol" => $this->addLabel(MCI_Footnotes_Settings::C_STR_HYPERLINK_ARROW, __("Select or input the backlink symbol:", MCI_Footnotes_Config::C_STR_PLUGIN_NAME)), "symbol-options" => $this->addSelectBox(MCI_Footnotes_Settings::C_STR_HYPERLINK_ARROW, MCI_Footnotes_Convert::getArrow()), "symbol-custom" => $this->addTextBox(MCI_Footnotes_Settings::C_STR_HYPERLINK_ARROW_USER_DEFINED), "notice-symbol" => __("Your input overrides the selection.", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), @@ -819,6 +860,7 @@ class MCI_Footnotes_Layout_Settings extends MCI_Footnotes_LayoutEngine { * 2020-12-09T1113+0100 * * @since 2.2.2 migrate Custom CSS to a dedicated tab 2020-12-15T0506+0100 + * @since 2.3.0 say 'copy-paste' instead of 'cut and paste', since cutting is not needed 2020-12-27T1257+0100 */ public function CustomCSS() { // load template file @@ -828,7 +870,7 @@ class MCI_Footnotes_Layout_Settings extends MCI_Footnotes_LayoutEngine { array( "label-css" => $this->addLabel(MCI_Footnotes_Settings::C_STR_CUSTOM_CSS, __("Your existing Custom CSS code:", MCI_Footnotes_Config::C_STR_PLUGIN_NAME)), "css" => $this->addTextArea(MCI_Footnotes_Settings::C_STR_CUSTOM_CSS), - "description-css" => __('Custom CSS migrates to a dedicated tab. This text area is intended to keep your data safe. Please cut and paste the content into the new text area under the new tab.', MCI_Footnotes_Config::C_STR_PLUGIN_NAME), + "description-css" => __('Custom CSS migrates to a dedicated tab. This text area is intended to keep your data safe. Please copy-paste the content into the new text area under the new tab.', MCI_Footnotes_Config::C_STR_PLUGIN_NAME), // CSS classes are listed in the template. // Localized notices are dropped to ease translators’ task. @@ -851,6 +893,13 @@ class MCI_Footnotes_Layout_Settings extends MCI_Footnotes_LayoutEngine { } public function CustomCSSMigration() { + + // options for Yes/No select box: + $l_arr_Enabled = array( + "yes" => __("Yes", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), + "no" => __("No", MCI_Footnotes_Config::C_STR_PLUGIN_NAME) + ); + // load template file $l_obj_Template = new MCI_Footnotes_Template(MCI_Footnotes_Template::C_STR_DASHBOARD, "customize-css-migration"); // replace all placeholders @@ -858,11 +907,13 @@ class MCI_Footnotes_Layout_Settings extends MCI_Footnotes_LayoutEngine { array( "label-css" => $this->addLabel(MCI_Footnotes_Settings::C_STR_CUSTOM_CSS, __("Your existing Custom CSS code:", MCI_Footnotes_Config::C_STR_PLUGIN_NAME)), "css" => $this->addTextArea(MCI_Footnotes_Settings::C_STR_CUSTOM_CSS), - "description-css" => __('Custom CSS migrates to a dedicated tab. This text area is intended to keep your data safe. Please copy and paste the content into the new text area below.', MCI_Footnotes_Config::C_STR_PLUGIN_NAME), + "description-css" => __('Custom CSS migrates to a dedicated tab. This text area is intended to keep your data safe. Please copy-paste the content into the new text area below.', MCI_Footnotes_Config::C_STR_PLUGIN_NAME), - "label-migrated" => $this->addLabel(MCI_Footnotes_Settings::C_BOOL_CUSTOM_CSS_MIGRATED, "Custom CSS migration complete:"), - "migrated" => $this->addCheckbox(MCI_Footnotes_Settings::C_BOOL_CUSTOM_CSS_MIGRATED), - "notice-migrated" => __("Please check this box when you are done migrating. After saving while this box is checked, the legacy Custom CSS containers are going to disappear.", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), + "label-show-legacy" => $this->addLabel(MCI_Footnotes_Settings::C_BOOL_CUSTOM_CSS_LEGACY_ENABLE, "Show legacy Custom CSS settings containers:"), + "show-legacy" => $this->addSelectBox(MCI_Footnotes_Settings::C_BOOL_CUSTOM_CSS_LEGACY_ENABLE, $l_arr_Enabled), + "notice-show-legacy" => __("Please set to No when you are done migrating, for the legacy Custom CSS containers to disappear.", MCI_Footnotes_Config::C_STR_PLUGIN_NAME), + // The placeholder is the “Referrers and tooltips” settings tab name. + "description-show-legacy" => sprintf(__('The legacy Custom CSS under the %s tab and its mirror here are emptied, and the select box saved as No, when the settings tab is saved while the settings container is not displayed.', MCI_Footnotes_Config::C_STR_PLUGIN_NAME), __("Referrers and tooltips", MCI_Footnotes_Config::C_STR_PLUGIN_NAME)), ) ); diff --git a/class/settings.php b/class/settings.php index 17f42bc..fff7bca 100644 --- a/class/settings.php +++ b/class/settings.php @@ -33,8 +33,12 @@ * @since 2.2.9 set default priority level of widget_text to 98 like for the_content (since 2.1.6), thanks to @marthalindeman 2020-12-25T1646+0100 * @since 2.2.10 reference container row border option, thanks to @noobishh 2020-12-25T2316+0100 * @see + * @since 2.3.0 reference container: settings for top (and bottom) margin, thanks to @hamshe + * @see + * @since 2.3.0 referrers, reference container: settings for anchor slugs + * @since 2.3.0 swap Custom CSS migration Boolean from 'migration complete' to 'show legacy' 2020-12-27T1243+0100 * - * Last modified: 2020-12-25T2336+0100 + * Last modified: 2020-12-29T1331+0100 */ @@ -327,18 +331,24 @@ class MCI_Footnotes_Settings { const C_STR_HYPERLINK_ARROW_USER_DEFINED = "footnote_inputfield_custom_hyperlink_symbol_user"; /** - * Settings Container Key for the user defined styling. + * Settings Container Key for the Custom CSS. * * @author Stefan Herndler * @since 1.5.0 * @var string * + * Edited heading 2020-12-27T1233+0100 * Edited: * @since 2.2.2 migrate Custom CSS to a dedicated tab 2020-12-15T0520+0100 + * @var string|bool + * + * @since 2.3.0 swap Boolean from 'migration complete' to 'show legacy' 2020-12-27T1233+0100 + * The Boolean must be false if its setting is contained in the container to be hidden, + * because when saving, all missing constants are zeroed, i.e. this is set to false. */ - const C_STR_CUSTOM_CSS = "footnote_inputfield_custom_css"; - const C_STR_CUSTOM_CSS_NEW = "footnote_inputfield_custom_css_new"; - const C_BOOL_CUSTOM_CSS_MIGRATED = "footnote_inputfield_custom_css_migrated"; + const C_STR_CUSTOM_CSS = "footnote_inputfield_custom_css"; + const C_STR_CUSTOM_CSS_NEW = "footnote_inputfield_custom_css_new"; + const C_BOOL_CUSTOM_CSS_LEGACY_ENABLE = "footnote_inputfield_custom_css_legacy_enable"; /** * Settings Container Key the activation of the_title hook. @@ -538,6 +548,26 @@ class MCI_Footnotes_Settings { */ const C_BOOL_REFERENCE_CONTAINER_ROW_BORDERS_ENABLE = "footnotes_inputfield_reference_container_row_borders_enable"; + /** + * Settings container keys for reference container top and bottom margins + * Settings container keys for hard link enabling + * Settings container keys for hard link anchors in referrers and footnotes + * + * @since 2.3.0 + * @var int|bool|str + * + * 2020-12-29T0914+0100 + */ + const C_INT_REFERENCE_CONTAINER_TOP_MARGIN = "footnotes_inputfield_reference_container_top_margin"; + const C_INT_REFERENCE_CONTAINER_BOTTOM_MARGIN = "footnotes_inputfield_reference_container_bottom_margin"; + const C_BOOL_FOOTNOTES_HARD_LINKS_ENABLE = "footnotes_inputfield_hard_links_enable"; + const C_STR_REFERRER_FRAGMENT_ID_SLUG = "footnotes_inputfield_referrer_fragment_id_slug"; + const C_STR_FOOTNOTE_FRAGMENT_ID_SLUG = "footnotes_inputfield_footnote_fragment_id_slug"; + const C_STR_HARD_LINK_IDS_SEPARATOR = "footnotes_inputfield_hard_link_ids_separator"; + + /** + * SETTINGS STORAGE + */ /** * Stores a singleton reference of this class. @@ -591,6 +621,10 @@ class MCI_Footnotes_Settings { self::C_STR_FOOTNOTES_COUNTER_STYLE => 'arabic_plain', self::C_BOOL_COMBINE_IDENTICAL_FOOTNOTES => 'yes', + self::C_BOOL_FOOTNOTES_HARD_LINKS_ENABLE => 'no', + self::C_STR_REFERRER_FRAGMENT_ID_SLUG => 'r', + self::C_STR_FOOTNOTE_FRAGMENT_ID_SLUG => 'f', + self::C_STR_HARD_LINK_IDS_SEPARATOR => '+', self::C_INT_FOOTNOTES_SCROLL_OFFSET => 20, self::C_INT_FOOTNOTES_SCROLL_DURATION => 380, @@ -605,6 +639,10 @@ class MCI_Footnotes_Settings { // whether to enqueue additional style sheet: self::C_STR_FOOTNOTES_PAGE_LAYOUT_SUPPORT => 'none', + + // top and bottom margins: + self::C_INT_REFERENCE_CONTAINER_TOP_MARGIN => 24, + self::C_INT_REFERENCE_CONTAINER_BOTTOM_MARGIN => 0, // table cell borders: self::C_BOOL_REFERENCE_CONTAINER_ROW_BORDERS_ENABLE => 'no', @@ -781,8 +819,8 @@ class MCI_Footnotes_Settings { "footnotes_storage_custom_css" => array( - self::C_STR_CUSTOM_CSS_NEW => '', - self::C_BOOL_CUSTOM_CSS_MIGRATED => '', + self::C_BOOL_CUSTOM_CSS_LEGACY_ENABLE => 'yes', + self::C_STR_CUSTOM_CSS_NEW => '', ), diff --git a/class/task.php b/class/task.php index 8a170a3..9b5e541 100644 --- a/class/task.php +++ b/class/task.php @@ -13,7 +13,7 @@ * * @since 2.0.9 DISABLED the_post HOOK 2020-11-08T1839+0100 * - * @since 2.1.0 promoted the 'Continue reading' button from localization to customization 2020-11-08T2146+0100 + * @since 2.1.0 promote the 'Continue reading' button from localization to configuration 2020-11-08T2146+0100 * @since 2.1.1 combining identical footnotes: fixed dead links, thanks to @happyches 2020-11-14T2233+0100 * @see * @since 2.1.1 fix start pages by option to hide ref container, thanks to @dragon013 @@ -58,8 +58,14 @@ * @since 2.2.10 URL wrap: support also file transfer protocol URLs 2020-12-25T2220+0100 * @since 2.2.10 Reference container: add option for table borders to revert 2.0.0/2.0.1 change made on user request, thanks to @noobishh 2020-12-25T2304+0100 * @see + * @since 2.3.0 Reference container: convert top padding to margin and make it a setting, thanks to @hamshe + * @see + * @since 2.3.0 optional hard links in referrers and backlinks for AMP compatibility, thanks to @psykonevro and @martinneumannat + * @see + * @see + * @since 2.3.0 swap Custom CSS migration Boolean from 'migration complete' to 'show legacy' 2020-12-27T1243+0100 * - * Last modified: 2020-12-25T2352+0100 + * Last modified: 2020-12-31T1234+0100 */ // If called directly, abort: @@ -73,6 +79,10 @@ defined( 'ABSPATH' ) or die; */ class MCI_Footnotes_Task { + /** + * PROPERTIES + */ + /** * Contains all footnotes found on current public page. * @@ -131,6 +141,67 @@ class MCI_Footnotes_Task { */ public static $l_int_ReferenceContainerId = 1; + /** + * Hard links for AMP + * + * Optional hard links in referrers and backlinks for AMP compatibility + * + * Thanks to @psykonevro and @martinneumannat + * @see + * @see + * @since 2.3.0 + * @var bool|str|int + */ + public static $l_bool_HardLinksEnable = false; + public static $l_str_ReferrerLinkSlug = 'r'; + public static $l_str_FootnoteLinkSlug = 'f'; + public static $l_str_LinkIdsSeparator = '+'; + public static $l_str_PostContainerIdCompound = ''; + // scroll offset may now need to get into inline CSS: + public static $l_int_ScrollOffset = 0; + + /** + * OPTIONAL LINK ELEMENT FOR FOOTNOTE REFERRERS AND BACKLINKS + * + * STYLING: + * Link color is preferred for referrers and backlinks. + * Setting a global link color is a common feature in WordPress themes. + * CSS does not support identifiers for link colors (color: link | hover | active | visited) + * These are only supported as pseudo-classes of the link element. + * Hence the link element must be present for styling purposes. + * But styling these elements with the link color is not universally preferred. + * If not, the very presence of the link elements may need to be avoided. + * + * FUNCTIONALITY: + * Although widely used for that purpose, hyperlinks are disliked for footnote linking. + * Browsers may need to be prevented from logging these clicks in the browsing history, + * as logging compromises the usability of the 'return to previous' button in browsers. + * For that purpose, and for scroll animation, this linking is performed by JavaScript. + * + * Link elements also raise further concerns, so that their useless proliferation needs + * to be mitigated. By contrast, due to an insufficiency in the CSS standard, real link + * elements are required to get the link color, as opposed to named colors on the basis + * of the already supported pseudo-classes :link, :hover, :active and :visited that can + * still not be used in color names. + * + * @since 2.0.0 added the link elements with hard links + * @since 2.0.4 removed the hard links on user request + * @see + * @since 2.1.4 made link elements optional for styling purposes, 2020-11-25T1306+0100 + * @since 2.3.0 this variable keeps its default value if hard links are enabled 2020-12-30T2313+0100 + * + * @var str + */ + public static $l_str_LinkSpan = 'span'; + public static $l_str_LinkOpenTag = ''; + public static $l_str_LinkCloseTag = ''; + + + + /** + * METHODS + */ + /** * Register WordPress Hooks to replace Footnotes in the content of a public page. * @@ -220,6 +291,8 @@ class MCI_Footnotes_Task { * @since 2.1.4 tootip font size and backlink column width settings * @since 2.2.5 options for label element and label bottom border, thanks to @markhillyer 2020-12-18T1447+0100 * @see + * @since 2.3.0 Reference container: convert top padding to margin and make it a setting, thanks to @hamshe + * @see */ public function wp_head() { @@ -231,6 +304,15 @@ class MCI_Footnotes_Task { echo ".home .footnotes_reference_container { display: none; }\r\n"; } + // ref container top and bottom margins: + $l_int_ReferenceContainerTopMargin = intval(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_INT_REFERENCE_CONTAINER_TOP_MARGIN)); + $l_int_ReferenceContainerBottomMargin = intval(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_INT_REFERENCE_CONTAINER_BOTTOM_MARGIN)); + echo ".footnotes_reference_container {margin-top: "; + echo empty($l_int_ReferenceContainerTopMargin) ? '0' : $l_int_ReferenceContainerTopMargin; + echo "px !important; margin-bottom: "; + echo empty($l_int_ReferenceContainerBottomMargin) ? '0' : $l_int_ReferenceContainerBottomMargin; + echo "px !important;}\r\n"; + // ref container label bottom border: if (MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_REFERENCE_CONTAINER_LABEL_BOTTOM_BORDER))) { echo ".footnote_container_prepare > "; @@ -292,6 +374,15 @@ class MCI_Footnotes_Task { echo "}\r\n"; } + // hard links scroll offset: + self::$l_bool_HardLinksEnable = MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_FOOTNOTES_HARD_LINKS_ENABLE)); + self::$l_int_ScrollOffset = intval(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_INT_FOOTNOTES_SCROLL_OFFSET)); + if (self::$l_bool_HardLinksEnable) { + echo ".footnote_referrer_anchor, .footnote_item_anchor {bottom: "; + echo self::$l_int_ScrollOffset; + echo "vh;}\r\n"; + } + // tooltips: $l_bool_TooltipsEnabled = MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_FOOTNOTES_MOUSE_OVER_BOX_ENABLED)); $l_bool_AlternativeTooltipsEnabled = MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_FOOTNOTES_MOUSE_OVER_BOX_ALTERNATIVE)); @@ -409,8 +500,8 @@ class MCI_Footnotes_Task { } // set custom CSS to override settings, not conversely: - // if dashboard tab migration acknowledged, disable legacy in case it was not cut: - if (!MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_CUSTOM_CSS_MIGRATED))) { + // Legacy Custom CSS is used until it’s set to disappear after dashboard tab migration: + if (MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_CUSTOM_CSS_LEGACY_ENABLE))) { echo MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_STR_CUSTOM_CSS); } echo MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_STR_CUSTOM_CSS_NEW); @@ -668,7 +759,7 @@ class MCI_Footnotes_Task { } if (!$p_bool_HideFootnotesText) { - // load template file + // load two template files: if (MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_FOOTNOTES_MOUSE_OVER_BOX_ALTERNATIVE))) { $l_obj_Template = new MCI_Footnotes_Template(MCI_Footnotes_Template::C_STR_PUBLIC, "footnote-alternative"); } else { @@ -727,9 +818,11 @@ class MCI_Footnotes_Task { * @see * @see * @since 2.2.8 correct lookbehind by duplicating it with and without quotation mark class 2020-12-23T1107+0100 + * * @since 2.2.9 account for RFC 2396 allowed characters in parameter names 2020-12-24T1956+0100 * @see * @since 2.2.9 exclude URLs also where the equals sign is preceded by an entity or character reference 2020-12-25T1234+0100 + * * @since 2.2.10 support also file transfer protocol URLs 2020-12-25T2220+0100 */ if (MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_FOOTNOTE_URL_WRAP_ENABLED))) { @@ -739,6 +832,23 @@ class MCI_Footnotes_Task { // Text to be displayed instead of the footnote $l_str_FootnoteReplaceText = ""; + // whether hard links are enabled; relevant also below in ReferenceContainer(): + if (self::$l_bool_HardLinksEnable) { + + // get the configurable parts: + self::$l_str_ReferrerLinkSlug = MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_STR_REFERRER_FRAGMENT_ID_SLUG); + self::$l_str_FootnoteLinkSlug = MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_STR_FOOTNOTE_FRAGMENT_ID_SLUG); + self::$l_str_LinkIdsSeparator = MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_STR_HARD_LINK_IDS_SEPARATOR); + + // streamline ID concatenation: + self::$l_str_PostContainerIdCompound = self::$l_str_LinkIdsSeparator; + self::$l_str_PostContainerIdCompound .= self::$l_int_PostId; + self::$l_str_PostContainerIdCompound .= self::$l_str_LinkIdsSeparator; + self::$l_str_PostContainerIdCompound .= self::$l_int_ReferenceContainerId; + self::$l_str_PostContainerIdCompound .= self::$l_str_LinkIdsSeparator; + + } + // display the footnote referrers and the tooltips: if (!$p_bool_HideFootnotesText) { $l_int_Index = MCI_Footnotes_Convert::Index($l_int_FootnoteIndex, MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_STR_FOOTNOTES_COUNTER_STYLE)); @@ -753,49 +863,102 @@ class MCI_Footnotes_Task { if (is_int($l_int_MaxLength) && strlen($l_str_DummyText) > $l_int_MaxLength) { $l_str_ExcerptText = substr($l_str_DummyText, 0, $l_int_MaxLength); $l_str_ExcerptText = substr($l_str_ExcerptText, 0, strrpos($l_str_ExcerptText, ' ')); - $l_str_ExcerptText .= ' … '; - $l_str_ExcerptText .= ''; + $l_str_ExcerptText .= "_$l_int_Index');\""; + + // if enabled, add the hard link fragment ID: + if (self::$l_bool_HardLinksEnable) { + + $l_str_ExcerptText .= ' href="#'; + $l_str_ExcerptText .= self::$l_str_FootnoteLinkSlug; + $l_str_ExcerptText .= self::$l_str_PostContainerIdCompound; + $l_str_ExcerptText .= $l_int_Index; + $l_str_ExcerptText .= '"'; + } + + $l_str_ExcerptText .= '>'; $l_str_ExcerptText .= MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_STR_FOOTNOTES_TOOLTIP_READON_LABEL); - $l_str_ExcerptText .= ''; + $l_str_ExcerptText .= self::$l_bool_HardLinksEnable ? '' : ''; } } // define the HTML element to use for the referrers: if (MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_FOOTNOTES_REFERRER_SUPERSCRIPT_TAGS))) { + $l_str_SupSpan = 'sup'; + } else { + $l_str_SupSpan = 'span'; } - // determine whether the link element is used, see below in ReferenceContainer() - $l_str_LinkSpan = MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_LINK_ELEMENT_ENABLED)) ? 'a' : 'span'; + // whether hard links are enabled; relevant also below in ReferenceContainer(): + if (self::$l_bool_HardLinksEnable) { + self::$l_str_LinkSpan = 'a'; + self::$l_str_LinkCloseTag = ''; + // self::$l_str_LinkOpenTag will be defined as needed + + // compose hyperlink address (leading space is in template): + $l_str_FootnoteLinkArgument = 'href="#'; + $l_str_FootnoteLinkArgument .= self::$l_str_FootnoteLinkSlug; + $l_str_FootnoteLinkArgument .= self::$l_str_PostContainerIdCompound; + $l_str_FootnoteLinkArgument .= $l_int_Index; + $l_str_FootnoteLinkArgument .= '" class="footnote_hard_link"'; + + // compose offset anchor, an empty span child of empty span + // to prevent browsers from drawing tall dotted rectangles: + $l_str_ReferrerAnchorElement = ''; + + } else { + + // no hyperlink nor offset anchor needed: + $l_str_FootnoteLinkArgument = ''; + $l_str_ReferrerAnchorElement = ''; + + // whether the link element is used nevertheless for styling: + if ( MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_LINK_ELEMENT_ENABLED)) ) { + + self::$l_str_LinkSpan = 'a'; + self::$l_str_LinkOpenTag = ''; + self::$l_str_LinkCloseTag = ''; + + } + } // fill in 'templates/public/footnote.html': $l_obj_Template->replace( array( - "post_id" => self::$l_int_PostId, - "container_id" => self::$l_int_ReferenceContainerId, - "note_id" => $l_int_Index, - "link-start" => $l_str_LinkSpan == 'a' ? '' : '', - "link-end" => $l_str_LinkSpan == 'a' ? '' : '', - "sup-span" => $l_str_SupSpan, - "before" => MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_STR_FOOTNOTES_STYLING_BEFORE), - "index" => $l_int_Index, - "after" => MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_STR_FOOTNOTES_STYLING_AFTER), - "text" => MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_FOOTNOTES_MOUSE_OVER_BOX_ENABLED)) ? $l_str_ExcerptText : "", + "link-span" => self::$l_str_LinkSpan, + "post_id" => self::$l_int_PostId, + "container_id" => self::$l_int_ReferenceContainerId, + "note_id" => $l_int_Index, + "hard-link" => $l_str_FootnoteLinkArgument, + "sup-span" => $l_str_SupSpan, + "before" => MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_STR_FOOTNOTES_STYLING_BEFORE), + "index" => $l_int_Index, + "after" => MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_STR_FOOTNOTES_STYLING_AFTER), + "anchor-element" => $l_str_ReferrerAnchorElement, + "text" => MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_FOOTNOTES_MOUSE_OVER_BOX_ENABLED)) ? $l_str_ExcerptText : "", ) ); $l_str_FootnoteReplaceText = $l_obj_Template->getContent(); // reset the template $l_obj_Template->reload(); + if ( + // standard tooltip is enabled: MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_FOOTNOTES_MOUSE_OVER_BOX_ENABLED)) && !MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_FOOTNOTES_MOUSE_OVER_BOX_ALTERNATIVE)) ) { @@ -862,40 +1025,13 @@ class MCI_Footnotes_Task { } - /** - * OPTIONAL LINK ELEMENT FOR FOOTNOTE REFERRERS AND BACKLINKS - * - * STYLING: - * Link color is preferred for referrers and backlinks. - * Setting a global link color is a common feature in WordPress themes. - * CSS does not support identifiers for link colors (color: link | hover | active | visited) - * These are only supported as pseudo-classes of the link element. - * Hence the link element must be present for styling purposes. - * But styling these elements with the link color is not universally preferred. - * If not, the very presence of the link elements may need to be avoided. - * - * FUNCTIONALITY: - * Although widely used for that purpose, hyperlinks are disliked for footnote linking. - * Browsers may need to be prevented from logging these clicks in the browsing history, - * as logging compromises the usability of the 'return to previous' button in browsers. - * For that purpose, and for scroll animation, this linking is performed by JavaScript. - * - * - * @since 2.0.0 added the link elements with hard links - * @since 2.0.4 removed the hard links on user request - * @see - * @since 2.1.4 made link elements optional, 2020-11-25T1306+0100 - */ - $l_str_LinkSpan = MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_LINK_ELEMENT_ENABLED)) ? 'a' : 'span'; - - /** * FOOTNOTE INDEX BACKLINK SYMBOL * * @since 2.0.0 removed backlink symbol along with column 2 of the reference container * @since 2.0.3 prepended an arrow on user request * @since 2.0.4 restored the arrow select & symbol input setting - * @since 2.1.1 made the symbol optional instead of customizing it to invisible + * @since 2.1.1 made the symbol optional instead of configuring it to invisible */ if (MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_REFERENCE_CONTAINER_BACKLINK_SYMBOL_ENABLE))) { @@ -929,13 +1065,13 @@ class MCI_Footnotes_Task { * * Initially a comma was appended in this algorithm for enumerations. * The comma in enumerations is not generally preferred. - * @since 2.1.4 the separator is optional, has options, and is customizable: + * @since 2.1.4 the separator is optional, has options, and is configurable: */ // check if it is even enabled: if (MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_BACKLINKS_SEPARATOR_ENABLED))) { - // if so, check if it is customized: + // if so, check if it is freely configured: $l_str_Separator = MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_STR_BACKLINKS_SEPARATOR_CUSTOM); if (empty($l_str_Separator)) { @@ -960,13 +1096,13 @@ class MCI_Footnotes_Task { * Initially a dot was appended in the table row template. * @since 2.0.6 a dot after footnote numbers is discarded as not localizable; * making it optional was envisaged. - * @since 2.1.4 the terminator is optional, has options, and is customizable: + * @since 2.1.4 the terminator is optional, has options, and is configurable: */ // check if it is even enabled: if (MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_BACKLINKS_TERMINATOR_ENABLED))) { - // if so, check if it is customized: + // if so, check if it is input-configured: $l_str_Terminator = MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_STR_BACKLINKS_TERMINATOR_CUSTOM); if (empty($l_str_Terminator)) { @@ -1032,18 +1168,8 @@ class MCI_Footnotes_Task { } } - // SET SWITCH FLAG INDEPENDENTLY - - if (MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_REFERENCE_CONTAINER_BACKLINK_SYMBOL_SWITCH))) { - - $l_bool_SymbolSwitch = true; - - } else { - - $l_bool_SymbolSwitch = false; - - } - + // whether to switch backlink symbol and footnote number: + $l_bool_SymbolSwitch = MCI_Footnotes_Convert::toBool(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_BOOL_REFERENCE_CONTAINER_BACKLINK_SYMBOL_SWITCH)); // FILL IN THE TEMPLATE @@ -1060,34 +1186,74 @@ class MCI_Footnotes_Task { continue; } - // INDEX COLUMN WITH ONE BACKLINK PER TABLE ROW - - // Standard behavior appropriate for combining identicals turned off - // generate content of footnote index cell $l_int_FirstFootnoteIndex = ($l_int_Index + 1); // get the footnote index string and // keep supporting legacy index placeholder: - $l_str_FootnoteIndex = MCI_Footnotes_Convert::Index(($l_int_Index + 1), MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_STR_FOOTNOTES_COUNTER_STYLE)); + $l_str_FootnoteId = MCI_Footnotes_Convert::Index(($l_int_Index + 1), MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_STR_FOOTNOTES_COUNTER_STYLE)); + // INDEX COLUMN WITH ONE BACKLINK PER TABLE ROW + + // if enabled, and for the case the footnote is single, compose hard link: + if (self::$l_bool_HardLinksEnable) { + + // compose fragment ID anchor with offset, for use in reference container, an + // empty span child of empty span to avoid tall dotted rectangles in browser: + $l_str_FootnoteAnchorElement = ''; + + // compose optional hard link address: + $l_str_HardLinkAddress = ' href="#'; + $l_str_HardLinkAddress .= self::$l_str_ReferrerLinkSlug; + $l_str_HardLinkAddress .= self::$l_str_PostContainerIdCompound; + $l_str_HardLinkAddress .= $l_str_FootnoteId . '"'; + + // compose optional opening link tag with optional hard link, mandatory for instance: + self::$l_str_LinkOpenTag = 'get(MCI_Footnotes_Settings::C_BOOL_COMBINE_IDENTICAL_FOOTNOTES))) { - $l_str_FootnoteId = $l_str_FootnoteIndex; - - // in case the footnote is unique: - $l_str_FootnoteReference = "<$l_str_LinkSpan"; + // ID, optional hard link address, and class: + $l_str_FootnoteReference = '<' . self::$l_str_LinkSpan; $l_str_FootnoteReference .= ' id="footnote_plugin_reference_'; $l_str_FootnoteReference .= self::$l_int_PostId; $l_str_FootnoteReference .= '_' . self::$l_int_ReferenceContainerId; $l_str_FootnoteReference .= "_$l_str_FootnoteId\""; + if (self::$l_bool_HardLinksEnable) { + $l_str_FootnoteReference .= ' href="#'; + $l_str_FootnoteReference .= self::$l_str_ReferrerLinkSlug; + $l_str_FootnoteReference .= self::$l_str_PostContainerIdCompound; + $l_str_FootnoteReference .= $l_str_FootnoteId . '"'; + } $l_str_FootnoteReference .= ' class="footnote_backlink"'; - // the click event goes in the table cell: + // the click event goes in the table cell if footnote remains single: $l_str_BacklinkEvent = ' onclick="footnote_moveToAnchor_'; $l_str_BacklinkEvent .= self::$l_int_PostId; $l_str_BacklinkEvent .= '_' . self::$l_int_ReferenceContainerId; @@ -1096,24 +1262,35 @@ class MCI_Footnotes_Task { $l_str_BacklinkEvent .= '_' . self::$l_int_ReferenceContainerId; $l_str_BacklinkEvent .= "_$l_str_FootnoteId');\""; + // the dedicated template enumerating backlinks uses another variable: $l_str_FootnoteBacklinks = $l_str_FootnoteReference; - $l_str_FootnoteBacklinks .= $l_str_BacklinkEvent; + + // append the click event right to the backlink item for enumerations; + // else it goes in the table cell: + $l_str_FootnoteBacklinks .= $l_str_BacklinkEvent . '>'; + $l_str_FootnoteReference .= '>'; + + // append the optional offset anchor for hard links: + if (self::$l_bool_HardLinksEnable) { + $l_str_FootnoteReference .= $l_str_FootnoteAnchorElement; + $l_str_FootnoteBacklinks .= $l_str_FootnoteAnchorElement; + } // continue both single note and notes cluster, depending on switch option status: if ($l_bool_SymbolSwitch) { - $l_str_FootnoteReference .= ">$l_str_FootnoteId$l_str_FootnoteArrow"; - $l_str_FootnoteBacklinks .= ">$l_str_FootnoteId$l_str_FootnoteArrow"; + $l_str_FootnoteReference .= "$l_str_FootnoteId$l_str_FootnoteArrow"; + $l_str_FootnoteBacklinks .= "$l_str_FootnoteId$l_str_FootnoteArrow"; } else { - $l_str_FootnoteReference .= ">$l_str_FootnoteArrow$l_str_FootnoteId"; - $l_str_FootnoteBacklinks .= ">$l_str_FootnoteArrow$l_str_FootnoteId"; + $l_str_FootnoteReference .= "$l_str_FootnoteArrow$l_str_FootnoteId"; + $l_str_FootnoteBacklinks .= "$l_str_FootnoteArrow$l_str_FootnoteId"; } - // If that is the only footnote with this text, we’re nearly done. + // If that is the only footnote with this text, we’re almost done. // check if it isn't the last footnote in the array: if ($l_int_FirstFootnoteIndex < count(self::$a_arr_Footnotes)) { @@ -1127,31 +1304,44 @@ class MCI_Footnotes_Task { // if so, set the further footnote as empty so it won't be displayed later: self::$a_arr_Footnotes[$l_int_CheckIndex] = ""; - // cancel the event altogether: - $l_str_BacklinkEvent = ""; - - - // HERE GOES THE FRAGMENT IDENTIFIER AND THE BACKLINK TOO: - // add the footnote index to the actual index: + // set the flag to true for the combined status: + $l_bool_FlagCombined = true; // update the footnote ID: $l_str_FootnoteId = MCI_Footnotes_Convert::Index(($l_int_CheckIndex + 1), MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_STR_FOOTNOTES_COUNTER_STYLE)); // resume composing the backlinks enumeration: - $l_str_FootnoteBacklinks .= "$l_str_Separator"; - $l_str_FootnoteBacklinks .= "$l_str_LineBreak<$l_str_LinkSpan"; + $l_str_FootnoteBacklinks .= "$l_str_Separator'; + $l_str_FootnoteBacklinks .= $l_str_LineBreak; + $l_str_FootnoteBacklinks .= '<' . self::$l_str_LinkSpan; $l_str_FootnoteBacklinks .= ' id="footnote_plugin_reference_'; $l_str_FootnoteBacklinks .= self::$l_int_PostId; $l_str_FootnoteBacklinks .= '_' . self::$l_int_ReferenceContainerId; - $l_str_FootnoteBacklinks .= "_$l_str_FootnoteId"; - $l_str_FootnoteBacklinks .= '" class="footnote_backlink" '; - $l_str_FootnoteBacklinks .= 'onclick="footnote_moveToAnchor_'; + $l_str_FootnoteBacklinks .= "_$l_str_FootnoteId\""; + // insert the optional hard link address: + if (self::$l_bool_HardLinksEnable) { + $l_str_FootnoteBacklinks .= ' href="#'; + $l_str_FootnoteBacklinks .= self::$l_str_ReferrerLinkSlug; + $l_str_FootnoteBacklinks .= self::$l_str_PostContainerIdCompound; + $l_str_FootnoteBacklinks .= $l_str_FootnoteId . '"'; + } + $l_str_FootnoteBacklinks .= ' class="footnote_backlink"'; + $l_str_FootnoteBacklinks .= ' onclick="footnote_moveToAnchor_'; $l_str_FootnoteBacklinks .= self::$l_int_PostId; $l_str_FootnoteBacklinks .= '_' . self::$l_int_ReferenceContainerId; $l_str_FootnoteBacklinks .= "('footnote_plugin_tooltip_"; $l_str_FootnoteBacklinks .= self::$l_int_PostId; $l_str_FootnoteBacklinks .= '_' . self::$l_int_ReferenceContainerId; $l_str_FootnoteBacklinks .= "_$l_str_FootnoteId');\">"; + // append the offset anchor for optional hard links: + if (self::$l_bool_HardLinksEnable) { + $l_str_FootnoteBacklinks .= ''; + } $l_str_FootnoteBacklinks .= $l_bool_SymbolSwitch ? '' : $l_str_FootnoteArrow; $l_str_FootnoteBacklinks .= $l_str_FootnoteId; $l_str_FootnoteBacklinks .= $l_bool_SymbolSwitch ? $l_str_FootnoteArrow : ''; @@ -1160,8 +1350,9 @@ class MCI_Footnotes_Task { } } - $l_str_FootnoteReference .= "$l_str_Terminator"; - $l_str_FootnoteBacklinks .= "$l_str_Terminator"; + // append terminator and end tag: + $l_str_FootnoteReference .= $l_str_Terminator . ''; + $l_str_FootnoteBacklinks .= $l_str_Terminator . ''; } @@ -1173,26 +1364,29 @@ class MCI_Footnotes_Task { // or in 'templates/public/reference-container-body-switch.html' $l_obj_Template->replace( array( + // placeholder used in all templates: - "text" => $l_str_FootnoteText, + "text" => $l_str_FootnoteText, // used in standard layout W/O COMBINED FOOTNOTES: - "post_id" => self::$l_int_PostId, - "container_id" => self::$l_int_ReferenceContainerId, - "note_id" => MCI_Footnotes_Convert::Index($l_int_FirstFootnoteIndex, MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_STR_FOOTNOTES_COUNTER_STYLE)), - "link-start" => $l_str_LinkSpan == 'a' ? '' : '', - "link-end" => $l_str_LinkSpan == 'a' ? '' : '', - "link-span" => $l_str_LinkSpan, - "terminator" => $l_str_Terminator, + "post_id" => self::$l_int_PostId, + "container_id" => self::$l_int_ReferenceContainerId, + "note_id" => MCI_Footnotes_Convert::Index($l_int_FirstFootnoteIndex, MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_STR_FOOTNOTES_COUNTER_STYLE)), + "link-start" => self::$l_str_LinkOpenTag, + "link-end" => self::$l_str_LinkCloseTag, + "link-span" => self::$l_str_LinkSpan, + "terminator" => $l_str_Terminator, + "anchor-element" => $l_str_FootnoteAnchorElement, + "hard-link" => $l_str_HardLinkAddress, // used in standard layout WITH COMBINED IDENTICALS TURNED ON: - "pointer" => empty($l_str_BacklinkEvent) ? '' : ' pointer', - "event" => $l_str_BacklinkEvent, - "backlinks" => empty($l_str_BacklinkEvent) ? $l_str_FootnoteBacklinks : $l_str_FootnoteReference, + "pointer" => $l_bool_FlagCombined ? '' : ' pointer', + "event" => $l_bool_FlagCombined ? '' : $l_str_BacklinkEvent, + "backlinks" => $l_bool_FlagCombined ? $l_str_FootnoteBacklinks : $l_str_FootnoteReference, // Legacy placeholders for use in legacy layout templates: - "arrow" => $l_str_FootnoteArrow, - "index" => $l_str_FootnoteIndex, + "arrow" => $l_str_FootnoteArrow, + "index" => $l_str_FootnoteId, ) ); @@ -1219,7 +1413,7 @@ class MCI_Footnotes_Task { "button-style" => !$l_bool_CollapseDefault ? 'display: none;' : '', "style" => $l_bool_CollapseDefault ? 'display: none;' : '', "content" => $l_str_Body, - "scroll-offset" => (intval(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_INT_FOOTNOTES_SCROLL_OFFSET)) / 100), + "scroll-offset" => (self::$l_int_ScrollOffset / 100), "scroll-duration" => intval(MCI_Footnotes_Settings::instance()->get(MCI_Footnotes_Settings::C_INT_FOOTNOTES_SCROLL_DURATION)), ) ); diff --git a/css/layout-entry-content.css b/css/layout-entry-content.css index 0dcb570..153b05b 100644 --- a/css/layout-entry-content.css +++ b/css/layout-entry-content.css @@ -2,17 +2,21 @@ * Basic responsive layout for the entry content div * * Based on Hello Elementor v2.3.0 Basic responsive layout - * themes/hello-elementor/theme.css:8..31 - * licensed under GNU General Public License v3 or later + * themes/hello-elementor/theme.css:8..31 + * Licensed under GNU General Public License v3 or later; * License URI: https://www.gnu.org/licenses/gpl-3.0.html * * Since v2.1.4 of Footnotes * - * Last modified for v2.2.2 2020-12-15T1004+0100 - * Last modified for v2.2.5 2020-12-16T1321+0100 + * Modified for 2.2.2 2020-12-15T1004+0100 + * Modified for 2.2.5 2020-12-16T1321+0100 + * Modified for 2.3.0 2020-12-29T0207+0100 + * + * Last modified: 2020-12-29T0210+0100 * * The enqueuing of this style sheet is optional and can be - * enabled in the Reference container settings. + * enabled in the dashboard under General settings > + * Reference container > Apply basic responsive page layout. **/ /*********************************************************** @@ -33,49 +37,64 @@ that would apply if the page were not built with Elementor. This is mainly useful with Hello Elementor, but it may help fix also other themes like Twenty Twenty-One for display in older browsers not yet supporting CSS variables. + +Sources: +.entry .entry-content <= Twenty Nineteen */ -div.page-content, -div.entry-content { +.page-content, +.entry-content, +.entry .entry-content, +main .entry .entry-content { margin: 0 auto; } @media (max-width: 575px) { - div.page-content, - div.entry-content { - padding: 0 10px; + .page-content, + .entry-content, + .entry .entry-content, + main .entry .entry-content { + padding: 0 10px; } } @media (min-width: 576px) { - div.page-content, - div.entry-content { + .page-content, + .entry-content, + .entry .entry-content, + main .entry .entry-content { max-width: 500px; } } @media (min-width: 768px) { - div.page-content, - div.entry-content { + .page-content, + .entry-content, + .entry .entry-content, + main .entry .entry-content { max-width: 600px; } } @media (min-width: 992px) { - div.page-content, - div.entry-content { + .page-content, + .entry-content, + .entry .entry-content, + main .entry .entry-content { max-width: 800px; } } @media (min-width: 1200px) { - div.page-content, - div.entry-content { + .page-content, + .entry-content, + .entry .entry-content, + main .entry .entry-content { max-width: 960px; } } diff --git a/css/public.css b/css/public.css index 2166d1a..fd80797 100755 --- a/css/public.css +++ b/css/public.css @@ -5,7 +5,7 @@ * Created-Time: 16:21 * Since: 1.0 * - * Version: 2.2.10 + * Version: 2.3.0 * * Classes added to public.css may be added to the * list documenting CSS classes for Custom CSS if @@ -19,8 +19,9 @@ * @see * @since 2.1.6 set z-index to maximum 2147483647 to address display issues with overlay content, thanks to @russianicons * @see + * @since 2.3.0 offset anchors for optional hard links * - * Last modified: 2020-12-25T2357+0100 + * Last modified: 2020-12-31T1211+0100 */ @@ -76,6 +77,22 @@ word-break: break-all; word-wrap: break-word; } +/***************************************************** +Optional hard links + +Anchors with scroll offset +*/ + +.footnote_item_base, +.footnote_referrer_base { + position: absolute; +} + +.footnote_item_anchor, +.footnote_referrer_anchor { + position: relative; +} + /***************************************************** Footnote referrers and tooltips @@ -90,25 +107,30 @@ Classes: */ .footnote_referrer, -.footnote_referrer a, .footnote_referrer:link, -.footnote_referrer a:link, +.footnote_referrer:hover, +.footnote_referrer > a, +.footnote_referrer > a:link, +.footnote_referrer > a:hover, +.footnote_plugin_tooltip_text, +.footnote_plugin_tooltip_text:hover, .main-content .footnote_referrer, -.main-content .footnote_referrer a, .main-content .footnote_referrer:link, -.main-content .footnote_referrer a:link, -.footnote_plugin_tooltip_text { +.main-content .footnote_referrer:hover, +.main-content .footnote_referrer > a, +.main-content .footnote_referrer > a:link, +.main-content .footnote_referrer > a:hover, +.main-content .footnote_plugin_tooltip_text, +.main-content .footnote_plugin_tooltip_text:hover { text-decoration: none !important; border-bottom: none !important; + box-shadow: none !important; +} + +.footnote_plugin_tooltip_text { line-height: 0; cursor: pointer; } -.footnote_referrer:hover, -.footnote_referrer a:hover, -.footnote_plugin_tooltip_text:hover { - text-decoration: none; - font-weight: inherit; -} /* tooltips @@ -208,6 +230,7 @@ Classes: .footnote_reference_container_collapse_button = sibling .footnote-reference-container = misleading and inconsistent; alias: .footnotes_table = +.footnotes_plugin_reference_row = .footnote_plugin_index_combi = first - - + +
if identical footnotes are combined .footnote_plugin_index = first if not .footnote_index = or in first in 3-column table diff --git a/css/settings.css b/css/settings.css index 918a7b8..6078fe0 100755 --- a/css/settings.css +++ b/css/settings.css @@ -5,9 +5,9 @@ * Created-Time: 16:21 * Since: 1.0 * - * Version: 2.2.10 + * Version: 2.3.0 * - * Last modified: 2020-12-25T2357+0100 + * Last modified: 2020-12-31T1026+0100 */ @@ -100,11 +100,14 @@ Limited to a number of IDs to not affect all dashboards width: 230px; } +#footnotes_inputfield_reference_container_top_margin, +#footnotes_inputfield_reference_container_bottom_margin, #footnotes_inputfield_backlinks_column_width_scalar, #footnotes_inputfield_backlinks_column_max_width_scalar, #footnotes_inputfield_mouse_over_box_font_size_scalar { width: 85px; } + #footnotes_inputfield_backlinks_column_width_unit, #footnotes_inputfield_backlinks_column_max_width_unit, #footnotes_inputfield_mouse_over_box_font_size_unit { diff --git a/footnotes.php b/footnotes.php index 4bc19f0..9e84d27 100755 --- a/footnotes.php +++ b/footnotes.php @@ -4,12 +4,12 @@ Plugin URI: https://wordpress.org/plugins/footnotes/ Description: time to bring footnotes to your website! footnotes are known from offline publishing and everybody takes them for granted when reading a magazine. Author: Mark Cheret - Version: 2.2.10 + Version: 2.3.0 Author URI: http://cheret.de/plugins/footnotes-2/ Text Domain: footnotes Domain Path: /languages */ -define( 'FOOTNOTES_VERSION', '2.2.10' ); +define( 'FOOTNOTES_VERSION', '2.3.0' ); /* Copyright 2020 Mark Cheret (email: mark@cheret.de) diff --git a/readme.txt b/readme.txt index 0039ed5..500f32d 100755 --- a/readme.txt +++ b/readme.txt @@ -80,13 +80,24 @@ Visit this swift write-up from a **footnotes** user by the name of **Southwest** == Changelog == += 2.3.0 = +- Add: optional hard links in referrers and backlinks for AMP compatibility, thanks to @psykonevro and @martinneumannat +- Bugfix: Reference container: convert top padding to margin and make it a setting, thanks to @hamshe +- Bugfix: Referrers and tooltips: disable box shadow to more effectively remove unwanted underline as bottom border, thanks to @klusik +- Bugfix: Dashboard: swap Custom CSS migration Boolean, meaning 'show legacy' instead of 'migration complete', due to storage data structure constraints +- Update: Dashboard: rename 'Priority level' tab as 'Scope and priority', to account for the new alternative depending on widget_text hook activation +- Bugfix: Referrers and tooltips: correct scope of the line height fix to only affect the referrers +- Bugfix: Referrers: extend clickable area to the full line height in sync with current pointer shape +- Bugfix: Referrers: extend scope of the underline inhibition to be more comprehensive and consistent +- Bugfix: Reference container: edits to optional basic responsive page layout style sheet + = 2.2.10 = - Bugfix: Reference container: add option for table borders to revert 2.0.0/2.0.1 change made on user request, thanks to @noobishh - Bugfix: Reference container: add missing container ID in function name in one of the four table row templates - Bugfix: Reference container, tooltips: URL wrap: support also file transfer protocol URLs = 2.2.9 = -- Bugfix: Reference containers, widget_text hook: support for multiple reference containers in a page, thanks to @justbecuz +- Bugfix: Reference container, widget_text hook: support for multiple reference containers in a page, thanks to @justbecuz - Update: Priority levels: set widget_text default to 98 and update its description in the dashboard Priority level tab - Bugfix: Reference container, tooltips: URL wrap: account for RFC 2396 allowed characters in parameter names - Bugfix: Reference container, tooltips: URL wrap: exclude URLs also where the equals sign is preceded by an entity or character reference diff --git a/templates/dashboard/customize-css-migration.html b/templates/dashboard/customize-css-migration.html index 4cc7a94..24c3830 100644 --- a/templates/dashboard/customize-css-migration.html +++ b/templates/dashboard/customize-css-migration.html @@ -8,8 +8,11 @@ [[css]]
[[label-migrated]][[migrated]] [[notice-migrated]][[label-show-legacy]][[show-legacy]] [[notice-show-legacy]]
+
+

[[description-show-legacy]]

+
diff --git a/templates/dashboard/customize-css-new.html b/templates/dashboard/customize-css-new.html index cfcf858..4ef3e3b 100644 --- a/templates/dashboard/customize-css-new.html +++ b/templates/dashboard/customize-css-new.html @@ -4,17 +4,19 @@ [[headline]]

.footnote_referrer = enclosing <span> +

.footnote_referrer > a = optional <a> enclosing the <sup>

.footnote_plugin_tooltip_text = inner <sup>, not tooltip -

+

.footnote_tooltip = inner <span>

.footnote_tooltip_continue = nested <span> -

+

.footnotes_reference_container = enclosing <div>

.footnote_container_prepare = label <div>

.footnote_reference_container_label = <span>

.footnote_reference_container_collapse_button = sibling <span> +

.footnotes_table = <table> -

+

.footnotes_plugin_reference_row = <tr>

.footnote_plugin_index_combi = first <td> if identical footnotes are combined

.footnote_plugin_index = first <td> if not

.footnote_index = <a> or <span> in first <td> in 3-column table diff --git a/templates/dashboard/settings-reference-container.html b/templates/dashboard/settings-reference-container.html index 9233ad6..e2769ae 100644 --- a/templates/dashboard/settings-reference-container.html +++ b/templates/dashboard/settings-reference-container.html @@ -12,10 +12,6 @@ [[label-border]] [[border]] - - [[label-row-borders]] - [[row-borders]] - [[label-collapse]] [[collapse]] @@ -28,6 +24,18 @@ [[label-shortcode]] [[shortcode]] [[notice-shortcode]] + + [[label-startpage]] + [[startpage]] + + + [[label-margin-top]] + [[margin-top]] [[notice-margin-top]] + + + [[label-margin-bottom]] + [[margin-bottom]] [[notice-margin-bottom]] + [[label-page-layout]] [[page-layout]] [[notice-page-layout]] @@ -36,10 +44,6 @@ [[label-url-wrap]] [[url-wrap]] [[notice-url-wrap]] - - [[label-startpage]] - [[startpage]] - [[label-symbol]] [[symbol-enable]] [[notice-symbol]] @@ -50,10 +54,11 @@ [[label-3column]] - - [[3column]] - [[notice-3column]] - + [[3column]] [[notice-3column]] + + + [[label-row-borders]] + [[row-borders]] [[label-separator]] diff --git a/templates/dashboard/settings-scrolling.html b/templates/dashboard/settings-scrolling.html index 707e559..bf1ca11 100644 --- a/templates/dashboard/settings-scrolling.html +++ b/templates/dashboard/settings-scrolling.html @@ -8,5 +8,21 @@ [[label-scroll-duration]] [[scroll-duration]] [[notice-scroll-duration]] + + [[label-hard-links]] + [[hard-links]] [[notice-hard-links]] + + + [[label-footnote]] + [[footnote]] [[notice-footnote]] + + + [[label-referrer]] + [[referrer]] [[notice-referrer]] + + + [[label-separator]] + [[separator]] [[notice-separator]] + diff --git a/templates/public/footnote-alternative.html b/templates/public/footnote-alternative.html index bae2f27..f0e415f 100644 --- a/templates/public/footnote-alternative.html +++ b/templates/public/footnote-alternative.html @@ -2,12 +2,15 @@ class="footnote_referrer relative" onmouseover="footnoteTooltipShow('footnote_plugin_tooltip_text_[[post_id]]_[[container_id]]_[[note_id]]')" onmouseout="footnoteTooltipHide('footnote_plugin_tooltip_text_[[post_id]]_[[container_id]]_[[note_id]]')" - >[[link-start]]<[[sup-span]] + ><[[link-span]] + onclick="footnote_moveToAnchor_[[post_id]]_[[container_id]]('footnote_plugin_reference_[[post_id]]_[[container_id]]_[[note_id]]');" + [[hard-link]] + ><[[sup-span]] id="footnote_plugin_tooltip_[[post_id]]_[[container_id]]_[[note_id]]" class="footnote_plugin_tooltip_text" - onclick="footnote_moveToAnchor_[[post_id]]_[[container_id]]('footnote_plugin_reference_[[post_id]]_[[container_id]]_[[note_id]]');" >[[before]][[index]][[after]][[link-end]][[anchor-element]]