From 25a208b27352c590e3be284e11f59a3d14d27341 Mon Sep 17 00:00:00 2001 From: Eyre_S Date: Fri, 3 Mar 2023 21:40:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8E=E7=AB=AF=E5=A4=A7=E6=94=B9=20progress?= =?UTF-8?q?-1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...read-card-markdown-compat-highlight-js.css | 0 ...card-markdown-enhanced-listing-rainbow.css | 0 .../bread-card-markdown-extension-shelf.css | 0 .../bread-card-markdown-footnote.css | 0 ...rd-markdown-heading-permalink-highlight.js | 0 .../bread-card-markdown-heading-permalink.css | 0 .../bread-card-markdown-task-list.css | 0 assets/{ => web}/bread-card-markdown.css | 0 assets/{ => web}/enhanced-rolling-title.js | 0 .../{ => web/lib}/utils-touchscreen-event.js | 0 assets/{ => web}/main.css | 0 assets/{ => web}/main.js | 3 +- assets/{ => web}/ref.css | 0 assets/{ => web}/ref.js | 0 composer.json | 5 +- constant.php | 4 +- index.php | 16 +++- src/Data/Bookshelf/NodeBookshelf.php | 67 +++++++++++++++++ .../Configuration/ConfigurationManager.php | 6 ++ src/Data/Configuration/ConfigurationScope.php | 9 +++ src/Data/Configuration/ConfigurationType.php | 16 ++++ .../ConfigurationTypesScopeShelf.php | 23 ++++++ src/Element/Book.php | 4 +- src/Element/BookCollection.php | 2 +- src/Element/BookContent/Chapter.php | 2 +- src/Element/BookContent/Page.php | 3 +- src/{Data => }/PageMeta.php | 4 +- src/{Data => }/SiteConfig/ConfigName.php | 2 +- src/{Data => }/SiteConfig/RobotsPolicy.php | 2 +- src/{Data => }/SiteMeta.php | 6 +- src/Utils/DOMHtml.php | 37 ++++++++++ src/Utils/DOMXMLTools.php | 19 +++++ src/Utils/Resources.php | 15 ++++ src/Web/Html/Body.php | 59 +++++++++++++++ src/Web/Html/Head.php | 50 +++++++++++++ src/Web/Html/Sidebar/Sidebar.php | 70 ++++++++++++++++++ src/Web/HtmlPage.php | 45 ++++++++++++ src/Web/WebResManager.php | 73 +++++++++++++++++++ src/Web/WebResource/IWebResource.php | 12 +++ src/Web/WebResource/JavascriptRaw.php | 23 ++++++ src/Web/WebResource/JavascriptRef.php | 21 ++++++ src/Web/WebResource/StylesheetsRef.php | 21 ++++++ src/Web/WebWarn.php | 33 +++++++++ template/footer.php | 8 +- template/header.php | 14 +++- template/nav.php | 5 +- template/raw-article.php | 2 +- template/raw-book-contents.php | 2 +- 48 files changed, 652 insertions(+), 31 deletions(-) rename assets/{ => web}/bread-card-markdown-compat-highlight-js.css (100%) rename assets/{ => web}/bread-card-markdown-enhanced-listing-rainbow.css (100%) rename assets/{ => web}/bread-card-markdown-extension-shelf.css (100%) rename assets/{ => web}/bread-card-markdown-footnote.css (100%) rename assets/{ => web}/bread-card-markdown-heading-permalink-highlight.js (100%) rename assets/{ => web}/bread-card-markdown-heading-permalink.css (100%) rename assets/{ => web}/bread-card-markdown-task-list.css (100%) rename assets/{ => web}/bread-card-markdown.css (100%) rename assets/{ => web}/enhanced-rolling-title.js (100%) rename assets/{ => web/lib}/utils-touchscreen-event.js (100%) rename assets/{ => web}/main.css (100%) rename assets/{ => web}/main.js (99%) rename assets/{ => web}/ref.css (100%) rename assets/{ => web}/ref.js (100%) create mode 100644 src/Data/Bookshelf/NodeBookshelf.php create mode 100644 src/Data/Configuration/ConfigurationManager.php create mode 100644 src/Data/Configuration/ConfigurationScope.php create mode 100644 src/Data/Configuration/ConfigurationType.php create mode 100644 src/Data/Configuration/ConfigurationTypesScopeShelf.php rename src/{Data => }/PageMeta.php (96%) rename src/{Data => }/SiteConfig/ConfigName.php (94%) rename src/{Data => }/SiteConfig/RobotsPolicy.php (64%) rename src/{Data => }/SiteMeta.php (96%) create mode 100644 src/Utils/DOMHtml.php create mode 100644 src/Utils/DOMXMLTools.php create mode 100644 src/Utils/Resources.php create mode 100644 src/Web/Html/Body.php create mode 100644 src/Web/Html/Head.php create mode 100644 src/Web/Html/Sidebar/Sidebar.php create mode 100644 src/Web/HtmlPage.php create mode 100644 src/Web/WebResManager.php create mode 100644 src/Web/WebResource/IWebResource.php create mode 100644 src/Web/WebResource/JavascriptRaw.php create mode 100644 src/Web/WebResource/JavascriptRef.php create mode 100644 src/Web/WebResource/StylesheetsRef.php create mode 100644 src/Web/WebWarn.php diff --git a/assets/bread-card-markdown-compat-highlight-js.css b/assets/web/bread-card-markdown-compat-highlight-js.css similarity index 100% rename from assets/bread-card-markdown-compat-highlight-js.css rename to assets/web/bread-card-markdown-compat-highlight-js.css diff --git a/assets/bread-card-markdown-enhanced-listing-rainbow.css b/assets/web/bread-card-markdown-enhanced-listing-rainbow.css similarity index 100% rename from assets/bread-card-markdown-enhanced-listing-rainbow.css rename to assets/web/bread-card-markdown-enhanced-listing-rainbow.css diff --git a/assets/bread-card-markdown-extension-shelf.css b/assets/web/bread-card-markdown-extension-shelf.css similarity index 100% rename from assets/bread-card-markdown-extension-shelf.css rename to assets/web/bread-card-markdown-extension-shelf.css diff --git a/assets/bread-card-markdown-footnote.css b/assets/web/bread-card-markdown-footnote.css similarity index 100% rename from assets/bread-card-markdown-footnote.css rename to assets/web/bread-card-markdown-footnote.css diff --git a/assets/bread-card-markdown-heading-permalink-highlight.js b/assets/web/bread-card-markdown-heading-permalink-highlight.js similarity index 100% rename from assets/bread-card-markdown-heading-permalink-highlight.js rename to assets/web/bread-card-markdown-heading-permalink-highlight.js diff --git a/assets/bread-card-markdown-heading-permalink.css b/assets/web/bread-card-markdown-heading-permalink.css similarity index 100% rename from assets/bread-card-markdown-heading-permalink.css rename to assets/web/bread-card-markdown-heading-permalink.css diff --git a/assets/bread-card-markdown-task-list.css b/assets/web/bread-card-markdown-task-list.css similarity index 100% rename from assets/bread-card-markdown-task-list.css rename to assets/web/bread-card-markdown-task-list.css diff --git a/assets/bread-card-markdown.css b/assets/web/bread-card-markdown.css similarity index 100% rename from assets/bread-card-markdown.css rename to assets/web/bread-card-markdown.css diff --git a/assets/enhanced-rolling-title.js b/assets/web/enhanced-rolling-title.js similarity index 100% rename from assets/enhanced-rolling-title.js rename to assets/web/enhanced-rolling-title.js diff --git a/assets/utils-touchscreen-event.js b/assets/web/lib/utils-touchscreen-event.js similarity index 100% rename from assets/utils-touchscreen-event.js rename to assets/web/lib/utils-touchscreen-event.js diff --git a/assets/main.css b/assets/web/main.css similarity index 100% rename from assets/main.css rename to assets/web/main.css diff --git a/assets/main.js b/assets/web/main.js similarity index 99% rename from assets/main.js rename to assets/web/main.js index 7de75a9..4ecb3a4 100644 --- a/assets/main.js +++ b/assets/web/main.js @@ -51,12 +51,11 @@ function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } -document.getElementById("sidebar-show").onclick = sidebarToggle; function sidebarToggle() { itemSidebar.parentElement.classList.toggle("show-sidebar"); } if (window.innerWidth > 1000) { sidebarToggle(); } - +document.getElementById("sidebar-show").onclick = sidebarToggle; EventUtil.bindEvent(itemSidebar, 'swipeleft', sidebarToggle) // EventUtil.bindEvent(document.body, 'swipeleft', function () { if (itemSidebar.parentElement.classList.contains("show-sidebar")) { sidebarToggle(); } }); // EventUtil.bindEvent(document.body, 'swiperight', function () { if (!itemSidebar.parentElement.classList.contains("show-sidebar")) { sidebarToggle(); } }); diff --git a/assets/ref.css b/assets/web/ref.css similarity index 100% rename from assets/ref.css rename to assets/web/ref.css diff --git a/assets/ref.js b/assets/web/ref.js similarity index 100% rename from assets/ref.js rename to assets/web/ref.js diff --git a/composer.json b/composer.json index 461d3f8..8efccee 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ } }, "require": { - "php": ">=8.1", + "php": ">=8.2", "ext-xml": "*", "ext-dom": "*", "ext-mbstring": "*", @@ -25,6 +25,7 @@ "league/commonmark": ">=2.3.8", "symfony/yaml": ">=4.0", "gregwar/rst": "^1.0", - "xemlock/php-latex": "dev-master" + "xemlock/php-latex": "dev-master", + "ext-simplexml": "*" } } diff --git a/constant.php b/constant.php index d7eecce..7c3b401 100644 --- a/constant.php +++ b/constant.php @@ -2,6 +2,8 @@ const APP_NAME = "ph-Bookshelf"; -const VERSION = "0.5.0-alpha1"; +const VERSION = "0.5.0-alpha2"; const CHANNEL = "suk-ws"; const BRANCH = "master"; + +const ON_DEVELOPMENT = true; diff --git a/index.php b/index.php index ca49a00..db54cae 100644 --- a/index.php +++ b/index.php @@ -3,11 +3,18 @@ require "./constant.php"; require "./vendor/autoload.php"; -use SukWs\Bookshelf\Data\PageMeta; -use SukWs\Bookshelf\Data\SiteConfig\RobotsPolicy; -use SukWs\Bookshelf\Data\SiteMeta; +use SukWs\Bookshelf\PageMeta; +use SukWs\Bookshelf\SiteConfig\RobotsPolicy; +use SukWs\Bookshelf\SiteMeta; use SukWs\Bookshelf\Utils\PageParse; use SukWs\Bookshelf\Utils\RequestNotExistException; +use SukWs\Bookshelf\Web\HtmlPage; + +$page = new HtmlPage(); + +echo $page->build()->document->saveHTML(); + +exit(); try { @@ -107,3 +114,6 @@ try { echo "

ERROR

" . $e->getMessage() . "

"; } + + + diff --git a/src/Data/Bookshelf/NodeBookshelf.php b/src/Data/Bookshelf/NodeBookshelf.php new file mode 100644 index 0000000..002abc8 --- /dev/null +++ b/src/Data/Bookshelf/NodeBookshelf.php @@ -0,0 +1,67 @@ +_Attr_version = $node_Bookshelf->attributes->getNamedItem("version")?->nodeValue; + // configure version check + if ($this->_Attr_version == null) WebWarn::output("bookshelf.xml:: file version is not declared.\n - the current ph-bookshelf uses version 2.0"); + else if ($this->_Attr_version != "2.0") throw new Exception("-0I{@EI[AID"); // todo throw exception + + /* @var DOMNode $dom_child */ + $dom_child = $node_Bookshelf->firstChild; + + /* == site_name == */ + if (!$dom_child->nodeName == "site_name") throw new Exception("O*R*OIArlAIWR"); // todo throw exception that site_name unavailable. + $this->_site_name = $dom_child->nodeValue; + $dom_child = $dom_child->nextSibling; + + /* == configurations == */ + if ($dom_child->nodeName == "configurations") { + $my_configurations = array(); + /* @var DOMElement $configNode */ + foreach ($dom_child->childNodes as $configNode) { + if (DOMXMLTools::isEmpty($configNode)) continue; + $my_configurations[$configNode->nodeName] = $configNode->nodeValue; + } + $this->_configurations = $my_configurations; + $dom_child = $dom_child->nextSibling; + } + + // todo elements. + + } + + /** + * @throws Exception + */ + public static function __load_from_xml(string $xml_string): NodeBookshelf { + $dom_tree = new DOMDocument(); + $dom_tree->loadXML($xml_string); // todo if load failed + $dom = $dom_tree->firstChild; + if ($dom instanceof DOMElement) + return new nodeBookshelf($dom); + throw new Exception("*@YUpoAWUIDP"); // todo if no root element + } + +} \ No newline at end of file diff --git a/src/Data/Configuration/ConfigurationManager.php b/src/Data/Configuration/ConfigurationManager.php new file mode 100644 index 0000000..120c85e --- /dev/null +++ b/src/Data/Configuration/ConfigurationManager.php @@ -0,0 +1,6 @@ +id = $id; + $this->scope = $scope; + } + +} \ No newline at end of file diff --git a/src/Data/Configuration/ConfigurationTypesScopeShelf.php b/src/Data/Configuration/ConfigurationTypesScopeShelf.php new file mode 100644 index 0000000..7c31cad --- /dev/null +++ b/src/Data/Configuration/ConfigurationTypesScopeShelf.php @@ -0,0 +1,23 @@ +createDocument(null, 'html', $dom->createDocumentType('html')); + } + + public static function createHeaderMeta (DOMDocument $root, array $metas): DOMElement { + $element = $root->createElement("meta"); + foreach ($metas as $name => $value) { + $element->setAttribute($name, $value); + } + return $element; + } + + public static function createStylesheetRef (DOMDocument $root, string $href): DOMElement { + $element = $root->createElement("link"); + $element->setAttribute("rel", "stylesheet"); + $element->setAttribute("href", $href); + return $element; + } + + public static function createScriptRef (DOMDocument $root, string $href): DOMElement { + $element = $root->createElement("script"); + $element->setAttribute("src", $href); + return $element; + } + +} \ No newline at end of file diff --git a/src/Utils/DOMXMLTools.php b/src/Utils/DOMXMLTools.php new file mode 100644 index 0000000..bc43736 --- /dev/null +++ b/src/Utils/DOMXMLTools.php @@ -0,0 +1,19 @@ +nodeName == "#comment") + return true; + if ($allow_empty_text && $element->nodeName == "#text" && empty(trim($element->nodeValue))) + return true; + if ($allow_cdata && $element->nodeName == "#cdata" && empty(trim($element->nodeValue))) + return true; + return false; + } + +} \ No newline at end of file diff --git a/src/Utils/Resources.php b/src/Utils/Resources.php new file mode 100644 index 0000000..4e661c4 --- /dev/null +++ b/src/Utils/Resources.php @@ -0,0 +1,15 @@ +root = $root; + $this->__self = $root->document->createElement("body"); + + $this->_sidebar = new Sidebar($this); + + } + + public function build (): DOMElement { + + $this->__self->appendChild($this->_sidebar->build()); + + foreach ($this->root->res_manager->getJavascriptLazyloadsDOM($this->root->document) as $script) + $this->__self->appendChild($script); + + // output the warnings message at the end. + $this->__self->appendChild(WebWarn::getWarningsAsJsLog()->build($this->root->document)); + + return $this->__self; + + } + + private static function getMain (DOMDocument $root): DOMElement { + + /* @var */ $main = $root->createElement("main"); + $main->setAttribute("id", "main"); + + /* @var */ $main_heading = $main->appendChild($root->createElement("div")); + $main_heading->setAttribute("id", "main-heading"); + + /* @var */ $page_tools = $main_heading->appendChild($root->createElement("div")); + $page_tools->setAttribute("id", "page-tools"); + /* @var */ $tool_sidebar_show = $page_tools->appendChild($root->createElement("button", "☰")); + $tool_sidebar_show->setAttribute("id", "sidebar-show"); + + return $main; + + } + +} diff --git a/src/Web/Html/Head.php b/src/Web/Html/Head.php new file mode 100644 index 0000000..2565ce3 --- /dev/null +++ b/src/Web/Html/Head.php @@ -0,0 +1,50 @@ +root = $root; + + $this->__self = $root->document->createElement("head"); + + $this->standard_headers = array( + DOMHtml::createHeaderMeta($root->document, array("charset" => "UTF-8")), + DOMHtml::createHeaderMeta($root->document, array("content" => "text/html; charset=UTF-8", "http-equiv" => "Content-Type")), + DOMHtml::createHeaderMeta($root->document, array("name" => "HandheldFriendly", "content" => "true")), + DOMHtml::createHeaderMeta($root->document, array("name" => "viewport", "content" => "width=device-width, initial-scale=1")), + DOMHtml::createHeaderMeta($root->document, array("name" => "apple-mobile-web-app-capable", "content" => "yes")), + DOMHtml::createHeaderMeta($root->document, array("name" => "apple-mobile-web-app-status-bar-style", "content" => "black")), + DOMHtml::createHeaderMeta($root->document, array("name" => "generator", "content" => "ph-Bookshelf ".VERSION)) + ); + + } + + public function build (): DOMElement { + + foreach ($this->standard_headers as $meta) + $this->__self->appendChild($meta); + + // todo maybe css js manager? + foreach ($this->root->res_manager->getStylesheetsDOM($this->root->document) as $style) + $this->__self->appendChild($style); + foreach ($this->root->res_manager->getJavascriptPreloadsDOM($this->root->document) as $script) + $this->__self->appendChild($script); + + return $this->__self; + + } + +} diff --git a/src/Web/Html/Sidebar/Sidebar.php b/src/Web/Html/Sidebar/Sidebar.php new file mode 100644 index 0000000..216e783 --- /dev/null +++ b/src/Web/Html/Sidebar/Sidebar.php @@ -0,0 +1,70 @@ +parent = $parent; + $this->root = $parent->root; + + $this->_sidebar_container = $this->root->document->createElement('div'); + $this->_sidebar_container->setAttribute('id', 'nav-container'); + + $this->_sidebar = $this->root->document->createElement('nav'); + $this->_sidebar->setAttribute('id', 'sidebar'); + $this->show_sidebar = false; + + $this->_sidebar_site_title_node = $this->root->document->createElement('a'); + $this->_sidebar_site_title_node->setAttribute('id','site-title'); + $this->_sidebar_site_title_node->setAttribute('class', 'no-style'); + $this->_sidebar_site_title_node->setAttribute('href', "/"); + $this->_sidebar_site_title_value = null; + + } + + public function toggleSidebarShow (?bool $show = null): void { + if ($show === null) $show = !$this->show_sidebar; + $this->show_sidebar = $show; + } + + public function setSiteTitle (string $title): void { + $this->_sidebar_site_title_value = $title; + } + + public function build (): DOMElement { + + if ($this->_sidebar_site_title_value == null) { + $this->_sidebar_site_title_value = "...not set"; + WebWarn::output("[Web]: Site Title not set yet."); + } + $this->_sidebar_site_title_node->appendChild( + $this->root->document->createTextNode($this->_sidebar_site_title_value)); + $this->_sidebar->appendChild($this->_sidebar_site_title_node); + + $this->_sidebar_container->appendChild($this->_sidebar); + if ($this->show_sidebar) + $this->_sidebar_container->setAttribute('class', 'show-sidebar'); + return $this->_sidebar_container; + + } + +} \ No newline at end of file diff --git a/src/Web/HtmlPage.php b/src/Web/HtmlPage.php new file mode 100644 index 0000000..c2f596b --- /dev/null +++ b/src/Web/HtmlPage.php @@ -0,0 +1,45 @@ +document = $document; + /* @var */ $dom_html = $document->documentElement; + $this->_html_html = $dom_html; + + $this->res_manager = new WebResManager(); + + /* @var */ $html_head = new Head($this); + $this->_html_head = $html_head; + /* @var */ $html_body = new Body($this); + $this->_html_body = $html_body; + + } + + public function build(): self { + $this->_html_html->appendChild($this->_html_head->build()); + $this->_html_html->appendChild($this->_html_body->build()); + return $this; + } + +} \ No newline at end of file diff --git a/src/Web/WebResManager.php b/src/Web/WebResManager.php new file mode 100644 index 0000000..8a61797 --- /dev/null +++ b/src/Web/WebResManager.php @@ -0,0 +1,73 @@ +stylesheets = self::getBasicCssList(); + $this->javascript_preload = array(); + $this->javascript_lazyload = self::getBasicJsLazyloadList(); + } + + /** @return DOMElement[] */ + public function getStylesheetsDOM (DOMDocument $root): array { + $return = array(); + foreach ($this->stylesheets as $item) { + $return[] = $item->build($root); + } + return $return; + } + + /** @return DOMElement[] */ + public function getJavascriptPreloadsDOM (DOMDocument $root): array { + $return = array(); + foreach ($this->javascript_preload as $item) { + $return[] = $item->build($root); + } + return $return; + } + + /** @return DOMElement[] */ + public function getJavascriptLazyloadsDOM (DOMDocument $root): array { + $return = array(); + foreach ($this->javascript_lazyload as $item) { + $return[] = $item->build($root); + } + return $return; + } + + /** @return StylesheetsRef[] */ + public static function getBasicCssList (): array { + return array( + new StylesheetsRef(Resources::webResPath('css', "main", 1)), + new StylesheetsRef(Resources::webResPath('css', "bread-card-markdown", 1)), + new StylesheetsRef(Resources::webResPath('css', "bread-card-markdown-footnote", 1)), + new StylesheetsRef(Resources::webResPath('css', "bread-card-markdown-task-list", 1)), + new StylesheetsRef(Resources::webResPath('css', "bread-card-markdown-heading-permalink", 1)), + new StylesheetsRef(Resources::webResPath('css', "bread-card-markdown-compat-highlight-js", 1)), + ); + } + + /** @return JavascriptRef[] */ + public static function getBasicJsLazyloadList (): array { + return array( + new JavascriptRef(Resources::webResPath('js', "lib/utils-touchscreen-event", 1)), + new JavascriptRef(Resources::webResPath('js', "main", 1)), + ); + } + +} diff --git a/src/Web/WebResource/IWebResource.php b/src/Web/WebResource/IWebResource.php new file mode 100644 index 0000000..2403347 --- /dev/null +++ b/src/Web/WebResource/IWebResource.php @@ -0,0 +1,12 @@ +javascript_raw_code = $code; + } + + public function build (DOMDocument $root): DOMElement { + $dom = $root->createElement('script'); + $dom_value = $root->createTextNode($this->javascript_raw_code); + $dom->appendChild($dom_value); + return $dom; + } + +} diff --git a/src/Web/WebResource/JavascriptRef.php b/src/Web/WebResource/JavascriptRef.php new file mode 100644 index 0000000..18c2040 --- /dev/null +++ b/src/Web/WebResource/JavascriptRef.php @@ -0,0 +1,21 @@ +uri = $uri; + } + + public function build (DOMDocument $root): DOMElement { + return DOMHtml::createScriptRef($root, $this->uri); + } + +} \ No newline at end of file diff --git a/src/Web/WebResource/StylesheetsRef.php b/src/Web/WebResource/StylesheetsRef.php new file mode 100644 index 0000000..1b4ea2b --- /dev/null +++ b/src/Web/WebResource/StylesheetsRef.php @@ -0,0 +1,21 @@ +uri = $uri; + } + + public function build (DOMDocument $root): DOMElement { + return DOMHtml::createStylesheetRef($root, $this->uri); + } + +} \ No newline at end of file diff --git a/src/Web/WebWarn.php b/src/Web/WebWarn.php new file mode 100644 index 0000000..8d51dc7 --- /dev/null +++ b/src/Web/WebWarn.php @@ -0,0 +1,33 @@ + - - + + + - - + + + + "> @@ -35,5 +36,12 @@ } + + appendChild($__web_js_warning_log); + echo $__web_js_warning_log_document->saveHTML(); + ?> diff --git a/template/nav.php b/template/nav.php index 94464ce..5ea4031 100644 --- a/template/nav.php +++ b/template/nav.php @@ -1,5 +1,6 @@ - - + +