From 2ff9de2b2d9270549d82475e2e045c92f37f81e5 Mon Sep 17 00:00:00 2001 From: Dierk Koenig Date: Sun, 31 Dec 2023 13:48:36 +0100 Subject: [PATCH] navigation: more streamlining and example inclusion --- .../getting-started-tutorial/app-solution.js | 2 +- .../getting-started-tutorial/index.html | 2 +- .../prototype/pages/pageController.js | 16 +- .../pages/person/personController.js | 2 +- .../prototype/pages/workday/dayController.js | 2 +- .../pages/workweek/workweek/weekController.js | 2 +- .../prototype/showcase-app/app.js | 24 ++- .../research/usertesting/app-template.js | 2 +- docs/img/icons/cute-robot.svg | 1 + docs/img/icons/left-arrow-gradient.svg | 9 + docs/img/icons/left-arrow.svg | 1 + docs/img/icons/line.svg | 3 + docs/img/icons/right-arrow-gray.svg | 3 + docs/src/examples/navigation/basic-nav-app.js | 57 +++++ .../examples/navigation/basic-nav-view.html | 50 +++++ .../pages/person/instantUpdateProjector.js | 8 +- .../navigation/pages/person/person.js | 2 +- .../pages/person/personController.js | 6 +- .../pages/person/personPageProjector.js | 2 +- .../simpleform/simpleFormPageProjector.js | 2 +- .../navigation/pages/static/about.css | 17 ++ .../navigation/pages/static/about.html | 10 + .../pages/{home => static}/home.css | 0 .../pages/{home => static}/home.html | 65 ++++++ .../style-guide/styleGuidePageProjector.js | 2 +- .../pages/style-guide/useStylesProjector.js | 4 +- .../pages/test-cases/testProjector.js | 4 +- .../navigation/pages/workday/dayController.js | 6 +- .../pages/workday/dayControllerTest.js | 2 +- .../pages/workday/simpleDayProjector.js | 4 +- .../pages/workweek/workWeekPageProjector.js | 2 +- .../workweek/workweek/simpleWeekProjector.js | 4 +- .../workweek/simpleWeekProjectorTest.js | 4 +- .../pages/workweek/workweek/weekController.js | 4 +- .../workweek/workweek/weekControllerTest.js | 2 +- .../navigation/navigationController.js | 128 ++++++------ .../navigation/navigationControllerTest.js | 10 +- .../src/kolibri/navigation/navigationModel.js | 47 ++--- .../projector/basicNavigationProjector.js | 3 +- .../breadcrumb/breadCrumbProjector.js | 4 +- .../bubble/bubbleNavigationProjector.js | 4 +- .../projector/card/cardNavigationProjector.js | 4 +- .../dashboardNavigationProjector.css | 138 +++++------- .../dashboard/dashboardNavigationProjector.js | 11 +- .../dashboardNavigationProjector2.css | 196 ------------------ .../flower/flowerNavigationProjector.js | 4 +- .../navigation/projector/navigation.css | 15 +- .../page/debugPage/debugPageProjector.js | 2 +- .../pageSwitch/pageSwitchProjector.js | 4 +- .../util/navigationProjectorTemplate.js | 10 +- 50 files changed, 443 insertions(+), 463 deletions(-) create mode 100644 docs/img/icons/cute-robot.svg create mode 100644 docs/img/icons/left-arrow-gradient.svg create mode 100644 docs/img/icons/left-arrow.svg create mode 100644 docs/img/icons/line.svg create mode 100644 docs/img/icons/right-arrow-gray.svg create mode 100644 docs/src/examples/navigation/basic-nav-app.js create mode 100644 docs/src/examples/navigation/basic-nav-view.html create mode 100644 docs/src/examples/navigation/pages/static/about.css create mode 100644 docs/src/examples/navigation/pages/static/about.html rename docs/src/examples/navigation/pages/{home => static}/home.css (100%) rename docs/src/examples/navigation/pages/{home => static}/home.html (61%) delete mode 100644 docs/src/kolibri/navigation/projector/dashboard/dashboardNavigationProjector2.css diff --git a/contrib/p6_schnidrig_altermatt/prototype/getting-started-tutorial/app-solution.js b/contrib/p6_schnidrig_altermatt/prototype/getting-started-tutorial/app-solution.js index edf4a13f..b32e05ad 100644 --- a/contrib/p6_schnidrig_altermatt/prototype/getting-started-tutorial/app-solution.js +++ b/contrib/p6_schnidrig_altermatt/prototype/getting-started-tutorial/app-solution.js @@ -1,5 +1,5 @@ import { PageController } from "../../prototype/pages/pageController.js"; -import { NavigationController } from "../../prototype/navigation/navigationController.js"; +import { NavigationController } from "../../../../docs/src/kolibri/navigation/navigationController.js"; import { PageProjector } from "./pages/pageProjector/pageProjector.js"; import { DebugPageProjector } from "./pages/debug/debugPageProjector.js"; import { NavigationProjector } from "./navigations/bubble-state/bubblestateNavigationProjector.js"; diff --git a/contrib/p6_schnidrig_altermatt/prototype/getting-started-tutorial/index.html b/contrib/p6_schnidrig_altermatt/prototype/getting-started-tutorial/index.html index 59d621c6..c0a732ec 100644 --- a/contrib/p6_schnidrig_altermatt/prototype/getting-started-tutorial/index.html +++ b/contrib/p6_schnidrig_altermatt/prototype/getting-started-tutorial/index.html @@ -28,5 +28,5 @@
- + diff --git a/contrib/p6_schnidrig_altermatt/prototype/pages/pageController.js b/contrib/p6_schnidrig_altermatt/prototype/pages/pageController.js index b490a1ef..4128c290 100644 --- a/contrib/p6_schnidrig_altermatt/prototype/pages/pageController.js +++ b/contrib/p6_schnidrig_altermatt/prototype/pages/pageController.js @@ -48,13 +48,13 @@ export { PageController } * @property { () => ?PageControllerType } getParent - a getter function that returns the parent of the page or null. See {@link setParent} for more details. * @property { (isNavigational: Boolean) => void } setNavigational - a setter function that sets the navigational state of the page. The navigational state declares if a page should be reachable through navigation or if an error should be returned to the user. Note: a page can be unnavigational but still visible meaning that a user can see the page in the navigation but cannot navigate to it directly with the hash. See {@link setVisible} if you want to make it invisible. * @property { () => Boolean } isNavigational - a getter function that returns the navigational state of the page. See {@link setNavigational} for more details. - * @property { (callback: onValueChangeCallback) => void } onActiveChanged - a function that registers an {@link onValueChangeCallback} that will be called whenever the active state changes. - * @property { (callback: onValueChangeCallback) => void } onIconPathChanged - a function that registers an {@link onValueChangeCallback} that will be called whenever the icon path changes. - * @property { (callback: onValueChangeCallback) => void } onVisitedChanged - a function that registers an {@link onValueChangeCallback} that will be called whenever the visited state changes. - * @property { (callback: onValueChangeCallback) => void } onValueChanged - a function that registers an {@link onValueChangeCallback} that will be called whenever the value changes. - * @property { (callback: onValueChangeCallback) => void } onNavigationalChanged - a function that registers an {@link onValueChangeCallback} that will be called whenever the navigational state changes. - * @property { (callback: onValueChangeCallback) => void } onVisibleChanged - a function that registers an {@link onValueChangeCallback} that will be called whenever the visible state changes. - * @property { (callback: onValueChangeCallback) => void } onParentChanged - a function that registers an {@link onValueChangeCallback} that will be called whenever the parent changes. + * @property { (callback: ValueChangeCallback) => void } onActiveChanged - a function that registers an {@link ValueChangeCallback} that will be called whenever the active state changes. + * @property { (callback: ValueChangeCallback) => void } onIconPathChanged - a function that registers an {@link ValueChangeCallback} that will be called whenever the icon path changes. + * @property { (callback: ValueChangeCallback) => void } onVisitedChanged - a function that registers an {@link ValueChangeCallback} that will be called whenever the visited state changes. + * @property { (callback: ValueChangeCallback) => void } onValueChanged - a function that registers an {@link ValueChangeCallback} that will be called whenever the value changes. + * @property { (callback: ValueChangeCallback) => void } onNavigationalChanged - a function that registers an {@link ValueChangeCallback} that will be called whenever the navigational state changes. + * @property { (callback: ValueChangeCallback) => void } onVisibleChanged - a function that registers an {@link ValueChangeCallback} that will be called whenever the visible state changes. + * @property { (callback: ValueChangeCallback) => void } onParentChanged - a function that registers an {@link ValueChangeCallback} that will be called whenever the parent changes. */ /** @@ -141,4 +141,4 @@ const PageController = (qualifier, dynamicContentControllers) => { onVisibleChanged: pageModel.getPageObs(VISIBLE).onChange, onParentChanged: pageModel.getPageObs(PARENT).onChange, } -}; \ No newline at end of file +}; diff --git a/contrib/p6_schnidrig_altermatt/prototype/pages/person/personController.js b/contrib/p6_schnidrig_altermatt/prototype/pages/person/personController.js index d3f7c52f..2b57be98 100644 --- a/contrib/p6_schnidrig_altermatt/prototype/pages/person/personController.js +++ b/contrib/p6_schnidrig_altermatt/prototype/pages/person/personController.js @@ -58,7 +58,7 @@ noSelection.detailed .getObs(VALUE) .setValue(false); // detail view can fo * @property { (T) => void } setSelectedModel * @property { () => T } getSelectedModel * @property { () => void } clearSelection - * @property { (callback: onValueChangeCallback) => void } onModelSelected + * @property { (callback: ValueChangeCallback) => void } onModelSelected */ /** diff --git a/contrib/p6_schnidrig_altermatt/prototype/pages/workday/dayController.js b/contrib/p6_schnidrig_altermatt/prototype/pages/workday/dayController.js index 653664b3..4f47a608 100644 --- a/contrib/p6_schnidrig_altermatt/prototype/pages/workday/dayController.js +++ b/contrib/p6_schnidrig_altermatt/prototype/pages/workday/dayController.js @@ -37,7 +37,7 @@ const DayModel = () => { * @property { SimpleInputControllerType } pmStartCtrl * @property { SimpleInputControllerType } pmEndCtrl * @property { () => Number } getTotal - the total minutes in this day, derived - * @property { (callback: !onValueChangeCallback) => void } onTotalChanged - when total changes + * @property { (callback: !ValueChangeCallback) => void } onTotalChanged - when total changes */ /** * Creating a day controller made from four simple input controllers for the four time values (as numbers diff --git a/contrib/p6_schnidrig_altermatt/prototype/pages/workweek/workweek/weekController.js b/contrib/p6_schnidrig_altermatt/prototype/pages/workweek/workweek/weekController.js index 6052c5dd..3c6ea847 100644 --- a/contrib/p6_schnidrig_altermatt/prototype/pages/workweek/workweek/weekController.js +++ b/contrib/p6_schnidrig_altermatt/prototype/pages/workweek/workweek/weekController.js @@ -31,7 +31,7 @@ const WeekModel = () => { /** * @typedef WeekControllerType * @property { (dayController: !DayControllerType ) => void } addDayController - * @property { (callback: !onValueChangeCallback) => void } onTotalWeekMinutesChanged + * @property { (callback: !ValueChangeCallback) => void } onTotalWeekMinutesChanged */ /** diff --git a/contrib/p6_schnidrig_altermatt/prototype/showcase-app/app.js b/contrib/p6_schnidrig_altermatt/prototype/showcase-app/app.js index 1ebdfa1e..7cbdf845 100644 --- a/contrib/p6_schnidrig_altermatt/prototype/showcase-app/app.js +++ b/contrib/p6_schnidrig_altermatt/prototype/showcase-app/app.js @@ -1,17 +1,17 @@ -import { NavigationController } from '../navigation/navigationController.js'; -import { CardNavigationProjector } from '../navigation/final-prototypes/card/cardNavigationProjector.js'; -import { DashboardRefinedProjector } from "../navigation/final-prototypes/dashboard-refined/dashboardRefinedNavigationProjector.js"; -import { FlowerNavigationProjector } from "../navigation/final-prototypes/flower/flowerNavigationProjector.js"; -import { BubbleStateNavigationProjector } from "../navigation/final-prototypes/bubble-state/bubblestateNavigationProjector.js"; -import { BreadCrumbProjector } from "../navigation/final-prototypes/bread-crumbs/breadCrumbProjector.js"; -import { PageSwitchProjector } from '../navigation/final-prototypes/page-switch/pageSwitchProjector.js'; +import { NavigationController } from '../../../../docs/src/kolibri/navigation/navigationController.js'; +import { CardNavigationProjector } from '../../../../docs/src/kolibri/navigation/projector/card/cardNavigationProjector.js'; +// import { DashboardRefinedProjector } from "../../../../docs/src/kolibri/navigation/projector/dashboard-refined/dashboardRefinedNavigationProjector.js"; +import { FlowerNavigationProjector } from "../../../../docs/src/kolibri/navigation/projector/flower/flowerNavigationProjector.js"; +import { BubbleStateNavigationProjector } from "../../../../docs/src/kolibri/navigation/projector/bubble/bubbleNavigationProjector.js"; +import { BreadCrumbProjector } from "../../../../docs/src/kolibri/navigation/projector/breadcrumb/breadCrumbProjector.js"; +// import { PageSwitchProjector } from '../../../../docs/src/kolibri/navigation/projector/page-switch/pageSwitchProjector.js'; import { PageController } from '../pages/pageController.js'; import { ForbiddenPageProjector } from '../pages/error-pages/403/forbiddenPageProjector.js'; import { PageNotFoundProjector } from '../pages/error-pages/404/pageNotFoundProjector.js'; import { StaticPageProjector } from '../pages/StaticPageProjector.js'; import { DebugPageProjector } from '../pages/debug/debugPageProjector.js'; import { StyleGuidePageProjector } from '../pages/style-guide/styleGuidePageProjector.js'; -import { SimpleFormController } from "../kolibri/projector/simpleForm/simpleFormController.js"; +import { SimpleFormController } from "../../../../docs/src/kolibri/projector/simpleForm/simpleFormController.js"; import { SimpleFormPageProjector } from "../pages/simpleform/simpleFormPageProjector.js"; import { TestCasesPageProjector } from "../pages/test-cases/testCasesPageProjector.js"; import { DayController } from "../pages/workday/dayController.js"; @@ -29,7 +29,7 @@ import { LOGO, NAME, NAVIGATIONAL, VALUE, VISIBLE -} from '../kolibri/presentationModel.js'; +} from '../../../../docs/src/kolibri/presentationModel.js'; import { CHECKBOX, COLOR, @@ -37,7 +37,11 @@ import { NUMBER, TEXT, TIME -} from "../kolibri/util/dom.js"; +} from "../../../../docs/src/kolibri/util/dom.js"; +import {PageSwitchProjector} from "../../../../docs/src/kolibri/navigation/projector/pageSwitch/pageSwitchProjector.js"; +import { + DashboardRefinedProjector +} from "../../../../docs/src/kolibri/navigation/projector/dashboard/dashboardNavigationProjector.js"; /* ********************************************* PIN TO ELEMENTS ************************************************************ */ const pinToCardNavElement = document.getElementById('card-nav'); diff --git a/contrib/p6_schnidrig_altermatt/research/usertesting/app-template.js b/contrib/p6_schnidrig_altermatt/research/usertesting/app-template.js index a0193cd9..b28740a2 100644 --- a/contrib/p6_schnidrig_altermatt/research/usertesting/app-template.js +++ b/contrib/p6_schnidrig_altermatt/research/usertesting/app-template.js @@ -1,5 +1,5 @@ import { PageController } from "../../prototype/pages/pageController.js"; -import { NavigationController } from "../../prototype/navigation/navigationController.js"; +// import { NavigationController } from "../../prototype/navigation/navigationController.js"; import { PageProjector } from "./pages/pageProjector/pageProjector.js"; import { DebugPageProjector } from "./pages/debug/debugPageProjector.js"; import { NavigationProjector } from "./navigations/bubble-state/bubblestateNavigationProjector.js"; diff --git a/docs/img/icons/cute-robot.svg b/docs/img/icons/cute-robot.svg new file mode 100644 index 00000000..8bb2014a --- /dev/null +++ b/docs/img/icons/cute-robot.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/img/icons/left-arrow-gradient.svg b/docs/img/icons/left-arrow-gradient.svg new file mode 100644 index 00000000..f7588d02 --- /dev/null +++ b/docs/img/icons/left-arrow-gradient.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/docs/img/icons/left-arrow.svg b/docs/img/icons/left-arrow.svg new file mode 100644 index 00000000..5ee24170 --- /dev/null +++ b/docs/img/icons/left-arrow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/img/icons/line.svg b/docs/img/icons/line.svg new file mode 100644 index 00000000..95505499 --- /dev/null +++ b/docs/img/icons/line.svg @@ -0,0 +1,3 @@ + + + diff --git a/docs/img/icons/right-arrow-gray.svg b/docs/img/icons/right-arrow-gray.svg new file mode 100644 index 00000000..191a4493 --- /dev/null +++ b/docs/img/icons/right-arrow-gray.svg @@ -0,0 +1,3 @@ + + + diff --git a/docs/src/examples/navigation/basic-nav-app.js b/docs/src/examples/navigation/basic-nav-app.js new file mode 100644 index 00000000..eb55139b --- /dev/null +++ b/docs/src/examples/navigation/basic-nav-app.js @@ -0,0 +1,57 @@ +import {PageController} from "../../kolibri/navigation/pageController.js"; +import {StaticPageProjector} from "../../kolibri/navigation/projector/page/staticPageProjector.js"; +import {NavigationController} from "../../kolibri/navigation/navigationController.js"; +import {NavigationProjector} from "../../kolibri/navigation/projector/basicNavigationProjector.js"; +import {DashboardRefinedProjector} from "../../kolibri/navigation/projector/dashboard/dashboardNavigationProjector.js"; + +// pages that will be displayed as content + +const homePageController = PageController("home", null); +homePageController.setIconPath('../../../img/icons/house.svg'); +StaticPageProjector( + /** @type { !PageControllerType } */ homePageController, + document.getElementById("content"), + './pages/static/home.html'); + + +const aboutPageController = PageController("about", null); +aboutPageController.setIconPath('../../../img/icons/cute-robot.svg'); +StaticPageProjector( + aboutPageController, + document.getElementById("content"), + './pages/static/about.html'); + +// navigation + +const navigationController = NavigationController(); +navigationController.setWebsiteLogo('../../../img/logo/logo.svg'); +navigationController.setWebsiteName('Basic Navigation'); + + +DashboardRefinedProjector(navigationController, document.getElementById("nav")); + +navigationController.addPageControllers( + homePageController, + aboutPageController +); + +navigationController.setHomeLocation(homePageController); + +// for later: more visualizations of the navigation +// const pinToBreadCrumbElement = document.getElementById('bread-crumbs'); +// BreadCrumbProjector(navigationController, pinToBreadCrumbElement); + + +/** + * If you'd like you can add our debugger below to your application to observe and alter some of your pages attributes + */ + +// const pinToDebugElement = document.getElementById("debug"); +// +// const debugPageController = PageController("debug", null); +// debugPageController.setIconPath('./pages/icons/bug.svg'); +// debugPageController.setVisible(false); +// DebugPageProjector(navigationController, debugPageController, pinToDebugElement); +// navigationController.addPageControllers(debugPageController); +// navigationController.setDebugMode(true); + diff --git a/docs/src/examples/navigation/basic-nav-view.html b/docs/src/examples/navigation/basic-nav-view.html new file mode 100644 index 00000000..73420922 --- /dev/null +++ b/docs/src/examples/navigation/basic-nav-view.html @@ -0,0 +1,50 @@ + + + + + + + (no title) + + + + + + + + + + + + + + + + + +
+ + + diff --git a/docs/src/examples/navigation/pages/person/instantUpdateProjector.js b/docs/src/examples/navigation/pages/person/instantUpdateProjector.js index 9aa91638..8149588f 100644 --- a/docs/src/examples/navigation/pages/person/instantUpdateProjector.js +++ b/docs/src/examples/navigation/pages/person/instantUpdateProjector.js @@ -1,7 +1,7 @@ -import { dom } from "../../kolibri/util/dom.js"; -import { VALUE } from "../../kolibri/presentationModel.js"; -import { projectInstantInput } from "../../kolibri/projector/simpleForm/simpleInputProjector.js"; -import { SimpleAttributeInputController } from "../../kolibri/projector/simpleForm/simpleInputController.js"; +import { dom } from "../../../../kolibri/util/dom.js"; +import { VALUE } from "../../../../kolibri/presentationModel.js"; +import { projectInstantInput } from "../../../../kolibri/projector/simpleForm/simpleInputProjector.js"; +import { SimpleAttributeInputController } from "../../../../kolibri/projector/simpleForm/simpleInputController.js"; export { projectListItem, selectListItemForModel, removeListItemForModel, projectForm, masterClassName, pageCss as personPageCss} diff --git a/docs/src/examples/navigation/pages/person/person.js b/docs/src/examples/navigation/pages/person/person.js index 3ec2df4f..9b9352d7 100644 --- a/docs/src/examples/navigation/pages/person/person.js +++ b/docs/src/examples/navigation/pages/person/person.js @@ -1,4 +1,4 @@ -import {Attribute, EDITABLE, LABEL, TYPE, VALUE, VALID } from "../../kolibri/presentationModel.js"; +import {Attribute, EDITABLE, LABEL, TYPE, VALUE, VALID } from "../../../../kolibri/presentationModel.js"; export { Person, reset, ALL_ATTRIBUTE_NAMES, selectionMold as personSelectionMold} diff --git a/docs/src/examples/navigation/pages/person/personController.js b/docs/src/examples/navigation/pages/person/personController.js index d3f7c52f..0a5b8f8d 100644 --- a/docs/src/examples/navigation/pages/person/personController.js +++ b/docs/src/examples/navigation/pages/person/personController.js @@ -4,8 +4,8 @@ * We do it anyway to follow the canonical structure of classical MVC where * views only ever know the controller API, not the model directly. */ -import { ObservableList, Observable } from "../../kolibri/observable.js"; -import { EDITABLE, VALUE } from "../../kolibri/presentationModel.js"; +import { ObservableList, Observable } from "../../../../kolibri/observable.js"; +import { EDITABLE, VALUE } from "../../../../kolibri/presentationModel.js"; import { Person, reset } from "./person.js"; export { ListController as PersonListController, SelectionController as PersonSelectionController } @@ -58,7 +58,7 @@ noSelection.detailed .getObs(VALUE) .setValue(false); // detail view can fo * @property { (T) => void } setSelectedModel * @property { () => T } getSelectedModel * @property { () => void } clearSelection - * @property { (callback: onValueChangeCallback) => void } onModelSelected + * @property { (callback: ValueChangeCallback) => void } onModelSelected */ /** diff --git a/docs/src/examples/navigation/pages/person/personPageProjector.js b/docs/src/examples/navigation/pages/person/personPageProjector.js index 298497a5..46a4d206 100644 --- a/docs/src/examples/navigation/pages/person/personPageProjector.js +++ b/docs/src/examples/navigation/pages/person/personPageProjector.js @@ -1,6 +1,6 @@ import { personProjectMasterView, personProjectDetailView } from "./masterDetailProjector.js"; import { personPageCss } from "./instantUpdateProjector.js"; -import { dom } from "../../kolibri/util/dom.js"; +import { dom } from "../../../../kolibri/util/dom.js"; export { PersonPageProjector } diff --git a/docs/src/examples/navigation/pages/simpleform/simpleFormPageProjector.js b/docs/src/examples/navigation/pages/simpleform/simpleFormPageProjector.js index 10f165b3..831a132a 100644 --- a/docs/src/examples/navigation/pages/simpleform/simpleFormPageProjector.js +++ b/docs/src/examples/navigation/pages/simpleform/simpleFormPageProjector.js @@ -1,4 +1,4 @@ -import { projectForm } from "../../kolibri/projector/simpleForm/simpleFormProjector.js" +import { projectForm } from "../../../../kolibri/projector/simpleForm/simpleFormProjector.js" export { SimpleFormPageProjector } diff --git a/docs/src/examples/navigation/pages/static/about.css b/docs/src/examples/navigation/pages/static/about.css new file mode 100644 index 00000000..a164bc42 --- /dev/null +++ b/docs/src/examples/navigation/pages/static/about.css @@ -0,0 +1,17 @@ +#content .about h1 { + margin-top: 35px; + color: var(--kb-hsla-primary-accent); +} + +#content .about .message-wrapper { + text-align: center; + padding: 16px; + display: flex; + justify-content: center; + color: var(--kb-hsla-primary-accent); +} + +#content .about button { + padding: 5px; + margin-top: 32px; +} diff --git a/docs/src/examples/navigation/pages/static/about.html b/docs/src/examples/navigation/pages/static/about.html new file mode 100644 index 00000000..cf5b87c5 --- /dev/null +++ b/docs/src/examples/navigation/pages/static/about.html @@ -0,0 +1,10 @@ +
+

About

+
+
+

These "buttons" should not be styled.

+ Home + No Style +
+
+
diff --git a/docs/src/examples/navigation/pages/home/home.css b/docs/src/examples/navigation/pages/static/home.css similarity index 100% rename from docs/src/examples/navigation/pages/home/home.css rename to docs/src/examples/navigation/pages/static/home.css diff --git a/docs/src/examples/navigation/pages/home/home.html b/docs/src/examples/navigation/pages/static/home.html similarity index 61% rename from docs/src/examples/navigation/pages/home/home.html rename to docs/src/examples/navigation/pages/static/home.html index cfa22883..43d19a57 100644 --- a/docs/src/examples/navigation/pages/home/home.html +++ b/docs/src/examples/navigation/pages/static/home.html @@ -1,4 +1,69 @@ +
+
diff --git a/docs/src/examples/navigation/pages/style-guide/styleGuidePageProjector.js b/docs/src/examples/navigation/pages/style-guide/styleGuidePageProjector.js index d36e1038..0e202a30 100644 --- a/docs/src/examples/navigation/pages/style-guide/styleGuidePageProjector.js +++ b/docs/src/examples/navigation/pages/style-guide/styleGuidePageProjector.js @@ -1,4 +1,4 @@ -import { dom } from "../../kolibri/util/dom.js"; +import { dom } from "../../../../kolibri/util/dom.js"; import { UseStylesProjector } from "./useStylesProjector.js"; export { StyleGuidePageProjector } diff --git a/docs/src/examples/navigation/pages/style-guide/useStylesProjector.js b/docs/src/examples/navigation/pages/style-guide/useStylesProjector.js index 67a14145..fb20e728 100644 --- a/docs/src/examples/navigation/pages/style-guide/useStylesProjector.js +++ b/docs/src/examples/navigation/pages/style-guide/useStylesProjector.js @@ -1,5 +1,5 @@ -import { dom } from "../../kolibri/util/dom.js" +import { dom } from "../../../../kolibri/util/dom.js" import { accentColor, okColor, neutralColor, selectColor, outputColor, shadowColor, shadowCss, primaryDark, primaryAccent, primaryBg, primaryLight, @@ -7,7 +7,7 @@ import { successAccent, successDark, successLight, successBg, warningAccent, warningDark, warningBg, warningLight, dangerAccent, dangerDark, dangerBg, dangerLight -} from "../../kolibri/style/kolibriStyle.js" +} from "../../../../kolibri/style/kolibriStyle.js" export { UseStylesProjector } diff --git a/docs/src/examples/navigation/pages/test-cases/testProjector.js b/docs/src/examples/navigation/pages/test-cases/testProjector.js index be793692..a3eb4374 100644 --- a/docs/src/examples/navigation/pages/test-cases/testProjector.js +++ b/docs/src/examples/navigation/pages/test-cases/testProjector.js @@ -1,6 +1,6 @@ import '../../kolibri/allKolibriTestsSuite.js'; -import { total, project } from "../../kolibri/util/test.js"; -import { versionInfo } from "../../kolibri/version.js"; +import { total, project } from "../../../../kolibri/util/test.js"; +import { versionInfo } from "../../../../kolibri/version.js"; export { TestProjector } diff --git a/docs/src/examples/navigation/pages/workday/dayController.js b/docs/src/examples/navigation/pages/workday/dayController.js index 653664b3..0bb07531 100644 --- a/docs/src/examples/navigation/pages/workday/dayController.js +++ b/docs/src/examples/navigation/pages/workday/dayController.js @@ -4,8 +4,8 @@ */ -import { SimpleInputController } from "../../kolibri/projector/simpleForm/simpleInputController.js"; -import { Attribute, VALUE } from "../../kolibri/presentationModel.js"; +import { SimpleInputController } from "../../../../kolibri/projector/simpleForm/simpleInputController.js"; +import { Attribute, VALUE } from "../../../../kolibri/presentationModel.js"; export { DayController } @@ -37,7 +37,7 @@ const DayModel = () => { * @property { SimpleInputControllerType } pmStartCtrl * @property { SimpleInputControllerType } pmEndCtrl * @property { () => Number } getTotal - the total minutes in this day, derived - * @property { (callback: !onValueChangeCallback) => void } onTotalChanged - when total changes + * @property { (callback: !ValueChangeCallback) => void } onTotalChanged - when total changes */ /** * Creating a day controller made from four simple input controllers for the four time values (as numbers diff --git a/docs/src/examples/navigation/pages/workday/dayControllerTest.js b/docs/src/examples/navigation/pages/workday/dayControllerTest.js index 1a4c422a..b9794353 100644 --- a/docs/src/examples/navigation/pages/workday/dayControllerTest.js +++ b/docs/src/examples/navigation/pages/workday/dayControllerTest.js @@ -1,6 +1,6 @@ // noinspection DuplicatedCode -import { TestSuite } from "../../kolibri/util/test.js"; +import { TestSuite } from "../../../../kolibri/util/test.js"; import { DayController } from "./dayController.js"; const dayControllerSuite = TestSuite("examples/workday/dayController"); diff --git a/docs/src/examples/navigation/pages/workday/simpleDayProjector.js b/docs/src/examples/navigation/pages/workday/simpleDayProjector.js index ec510cee..6c5dc855 100644 --- a/docs/src/examples/navigation/pages/workday/simpleDayProjector.js +++ b/docs/src/examples/navigation/pages/workday/simpleDayProjector.js @@ -1,5 +1,5 @@ -import { dom } from "../../kolibri/util/dom.js"; -import { projectChangeInput} from "../../kolibri/projector/simpleForm/simpleInputProjector.js"; +import { dom } from "../../../../kolibri/util/dom.js"; +import { projectChangeInput} from "../../../../kolibri/projector/simpleForm/simpleInputProjector.js"; export { projectDay } diff --git a/docs/src/examples/navigation/pages/workweek/workWeekPageProjector.js b/docs/src/examples/navigation/pages/workweek/workWeekPageProjector.js index d43fa6ff..f64bb079 100644 --- a/docs/src/examples/navigation/pages/workweek/workWeekPageProjector.js +++ b/docs/src/examples/navigation/pages/workweek/workWeekPageProjector.js @@ -1,5 +1,5 @@ import { projectWeek } from "./workweek/simpleWeekProjector.js"; -import { dom } from "../../kolibri/util/dom.js"; +import { dom } from "../../../../kolibri/util/dom.js"; export { WorkWeekPageProjector } diff --git a/docs/src/examples/navigation/pages/workweek/workweek/simpleWeekProjector.js b/docs/src/examples/navigation/pages/workweek/workweek/simpleWeekProjector.js index 42795d3d..9e7e1872 100644 --- a/docs/src/examples/navigation/pages/workweek/workweek/simpleWeekProjector.js +++ b/docs/src/examples/navigation/pages/workweek/workweek/simpleWeekProjector.js @@ -1,5 +1,5 @@ -import { dom } from "../../../kolibri/util/dom.js"; -import { totalMinutesToTimeString } from "../../../kolibri/projector/projectorUtils.js" +import { dom } from "../../../../../kolibri/util/dom.js"; +import { totalMinutesToTimeString } from "../../../../../kolibri/projector/projectorUtils.js" import { DayController } from "../../workday/dayController.js"; import { projectDay } from "../../workday/simpleDayProjector.js"; diff --git a/docs/src/examples/navigation/pages/workweek/workweek/simpleWeekProjectorTest.js b/docs/src/examples/navigation/pages/workweek/workweek/simpleWeekProjectorTest.js index c5849d4b..2846124c 100644 --- a/docs/src/examples/navigation/pages/workweek/workweek/simpleWeekProjectorTest.js +++ b/docs/src/examples/navigation/pages/workweek/workweek/simpleWeekProjectorTest.js @@ -1,8 +1,8 @@ -import { TestSuite } from "../../../kolibri/util/test.js"; +import { TestSuite } from "../../../../../kolibri/util/test.js"; import { WeekController } from "./weekController.js"; import { projectWeek } from "./simpleWeekProjector.js"; -import { fireChangeEvent } from "../../../kolibri/util/dom.js"; +import { fireChangeEvent } from "../../../../../kolibri/util/dom.js"; const simpleWeekProjectorSuite = TestSuite("examples/workweek/simpleWeekProjector"); diff --git a/docs/src/examples/navigation/pages/workweek/workweek/weekController.js b/docs/src/examples/navigation/pages/workweek/workweek/weekController.js index 6052c5dd..e47adfcd 100644 --- a/docs/src/examples/navigation/pages/workweek/workweek/weekController.js +++ b/docs/src/examples/navigation/pages/workweek/workweek/weekController.js @@ -4,7 +4,7 @@ * Collaborates with {@link DayController}. */ -import {Attribute, VALUE} from "../../../kolibri/presentationModel.js"; +import {Attribute, VALUE} from "../../../../../kolibri/presentationModel.js"; import "../../../kolibri/util/array.js" export { WeekController } @@ -31,7 +31,7 @@ const WeekModel = () => { /** * @typedef WeekControllerType * @property { (dayController: !DayControllerType ) => void } addDayController - * @property { (callback: !onValueChangeCallback) => void } onTotalWeekMinutesChanged + * @property { (callback: !ValueChangeCallback) => void } onTotalWeekMinutesChanged */ /** diff --git a/docs/src/examples/navigation/pages/workweek/workweek/weekControllerTest.js b/docs/src/examples/navigation/pages/workweek/workweek/weekControllerTest.js index bb35014f..9622d947 100644 --- a/docs/src/examples/navigation/pages/workweek/workweek/weekControllerTest.js +++ b/docs/src/examples/navigation/pages/workweek/workweek/weekControllerTest.js @@ -1,4 +1,4 @@ -import { TestSuite } from "../../../kolibri/util/test.js"; +import { TestSuite } from "../../../../../kolibri/util/test.js"; import { DayController } from "../../workday/dayController.js"; import { WeekController } from "./weekController.js"; diff --git a/docs/src/kolibri/navigation/navigationController.js b/docs/src/kolibri/navigation/navigationController.js index 93b32655..ba245185 100644 --- a/docs/src/kolibri/navigation/navigationController.js +++ b/docs/src/kolibri/navigation/navigationController.js @@ -1,13 +1,8 @@ - -// TODO: how to model HASH, PARENT, PATH, etc. - -// import { Attribute, HASH, PARENT, PATH, VALUE, valueOf } from "../kolibri/presentationModel.js"; -import {Location, NavigationModel} from "./navigationModel.js"; -import {Attribute, VALUE, valueOf} from "../presentationModel.js"; +import {NavigationModel, NO_SUCH_LOCATION} from "./navigationModel.js"; export { NavigationController, NAME, LOGO, FAVICON, HOMEPAGE, DEBUGMODE } -const NAME = "websiteName"; +const NAME = "websiteName"; const LOGO = "websiteLogo"; const FAVICON = "favicon"; const HOMEPAGE = "homepage"; @@ -30,8 +25,9 @@ const DEBUGMODE = "debugMode"; * @property { (pageHash: String) => void } deletePageController - deletes the page controller of a specific hash. * @property { (anchor: HTMLAnchorElement) => void } registerAnchorClickListener - registers a click listener on an anchor. this binding triggers a location change trough navigate based on the hash the anchor has. * @property { (confObj: ModelConfigurationObject) => boolean } setConfiguration - sets the attributes of this navigation for all keys in object to their value. + * @property { (hoshOfTheNewHome: String) => void } setHomeLocationByHash - * @property { (newHomepage: !PageControllerType) => void } setHomeLocation - sets the given PageController as the homepage. the homepage is the fallback page which gets opened when no hash is provided in the request url. Calling all registered {@link ValueChangeCallback}s. - * @property { () => ?PageControllerType} getHomeLocation - returns the PageController of the homepage. See {@link setHomeLocation} for more details. Returns null if no homepage has been defined. + * @property { () => ?LocationType} getHomeLocation - returns the PageController of the homepage. See {@link setHomeLocation} for more details. Returns null if no homepage has been defined. * @property { (newPath: String) => void } setPath - sets the current path. The path consists of the string that is passed after the '#' in the url. The path can be used for granular sub-routing. * @property { () => String} getPath - returns the current path. See {@link setPath} for more details. * @property { (name: String) => void } setWebsiteName - sets the name for the website, calling all registered {@link ValueChangeCallback}s. The name can be displayed by a {@link NavigationProjectorType}. @@ -42,8 +38,8 @@ const DEBUGMODE = "debugMode"; * @property { () => String } getFavIcon - returns the path to the favicon. See {@link setFavIcon} for more details. * @property { (debugModeActive: Boolean) => void } setDebugMode - sets the debug mode active state. calling all registered {@link ValueChangeCallback}s. * @property { () => Boolean } isDebugMode - returns if the debug mode is active. - * @property { (callback: ConsumerType) => Boolean } onNavigationHashAdd - registers an {@link ConsumerType} that will be called whenever a page hash is added. - * @property { (callback: ConsumerType) => Boolean } onNavigationHashDel - registers an {@link ConsumerType} that will be called whenever a page hash is deleted. + * @property { (callback: ConsumerType) => Boolean } onLocationAdded - registers an {@link ConsumerType} that will be called whenever a page hash is added. + * @property { (callback: ConsumerType) => Boolean } onLocationRemoved - registers an {@link ConsumerType} that will be called whenever a page hash is deleted. * @property { (callback: ValueChangeCallback) => void } onLocationChanged - registers an {@link ValueChangeCallback} that will be called whenever the current location is changed. * @property { (callback: ValueChangeCallback) => void } onPathChanged - registers an {@link ValueChangeCallback} that will be called whenever the current path is changed. * @property { (callback: ValueChangeCallback) => void } onWebsiteNameChanged - registers an {@link ValueChangeCallback} that will be called whenever the page name is changed. @@ -72,44 +68,41 @@ const NavigationController = () => { * activating / passivating the involved {@link PageControllerType controllers}. * * @function - * @param { String } hash - will be normalized to start with # sign + * @param { !String } hash - will be normalized to start with # sign * @return { void } * */ const navigateToHash = hash => { - // check if hash is empty to redirect to fallback homepage if ( ! hash.startsWith("#")) { // todo: find out if this ever happens hash = "#" + hash; } - // todo: this block should not be needed at all. - // if(hash === '' || hash === '#') { // todo: check if null - // const homepageController = navigationModel.getHomepage(); // todo: why is the homepage not part of the locations? - // if (null !== homepageController) { - // hash = homepageController.getHash(); - // } else { - // // return if fallback homepage is not defined - // // todo: check what happens here: error, log? - // return; - // } - // } + if(hash === '#') { // this is considered a reserved homepage hash + hash = navigationModel.getHomeLocation()?.getHash(); + } + + const newLocation = findTargetLocation(hash); + + if (NO_SUCH_LOCATION === newLocation) { + console.error("cannot find location for hash <"+hash+">"); // todo: proper logging + return; + } // todo: should this line move between passivation of last and activation of next location? window.location.hash = hash; // effect: navigate to hash, trigger hashchanged event (?), add to history - const newLocation = findTargetLocation(hash); // on initialization the currentLocation can be null and passivation should not fail in that case navigationModel.getCurrentLocation() ?. passivate(); - newLocation.pageController.activate(); + newLocation.activate(); navigationModel.setCurrentLocation(newLocation); if (navigationModel.isDebugMode()) { // todo: why is this done here? Shouldn't this be automatic on hash change? - const debugController = navigationModel.findLocationByHash('#debug').pageController; - debugController.setParent(newLocation.pageController); + const debugController = navigationModel.findLocationByHash('#debug'); + debugController.setParent(newLocation); } }; @@ -125,15 +118,25 @@ const NavigationController = () => { const targetLocation = navigationModel.findLocationByHash(hash); - if(targetLocation === navigationModel.NO_SUCH_LOCATION) { // if newLocation is undefined, navigate to an error page + if(targetLocation === NO_SUCH_LOCATION) { // if newLocation is undefined, navigate to an error page return navigationModel.findLocationByHash('#E404'); } - if (!targetLocation.pageController.isNavigational()) { // if the newLocation exists but is not navigational we return a 403 forbidden error + if (!targetLocation.isNavigational()) { // if the newLocation exists but is not navigational we return a 403 forbidden error return navigationModel.findLocationByHash('#E403'); } return targetLocation; }; + const setHomeLocationByHash = hash => { + const location = navigationModel.findLocationByHash(hash); + if (location === NO_SUCH_LOCATION) { + // todo: proper logging + console.error("hash <"+hash+"> cannot be found for setting the home location to. Is it registered?") + } else { + navigationModel.setHomeLocation( /** @type { !LocationType } */ location); + } + }; + // handles initial page load and page reload window.onload = () => { const hash = window.location.hash; @@ -143,29 +146,29 @@ const NavigationController = () => { // handles navigation through the browser URL field, bookmarking, or browser previous/next window.onhashchange = () => { const hash = window.location.hash; - if (hash !== navigationModel.getCurrentLocation()?.hash) { + if (hash !== navigationModel.getCurrentLocation()?.getHash()) { navigateToHash(hash); } }; const addLocation = newLocation => { - if (navigationModel.findLocationByHash(newLocation.hash) === navigationModel.NO_SUCH_LOCATION) { + if (navigationModel.findLocationByHash(newLocation.getHash()) === navigationModel.NO_SUCH_LOCATION) { navigationModel.addLocation(newLocation); } else { throw new Error('PageController could not be added to the NavigationModel. Please check that the hash is valid and has not already been added to the navigation: ' + newLocation.getHash()); } }; - return { - addPageController: pageController => addLocation(Location(pageController)), + return /** @type { NavigationControllerType } */{ + addPageController: pageController => addLocation(pageController), addPageControllers: (...pageControllersToAdd) => { for (const pageController of pageControllersToAdd) { - addLocation(Location(pageController)); + addLocation(pageController); } }, - getPageController: pageHash => navigationModel.findLocationByHash(pageHash)?.pageController, + getPageController: pageHash => navigationModel.findLocationByHash(pageHash), deletePageController: pageHash => { - navigationModel.removeLocation(pageHash); + navigationModel.removeLocationByHash(pageHash); }, registerAnchorClickListener: anchor => { anchor.onclick = e => { @@ -174,40 +177,39 @@ const NavigationController = () => { navigateToHash(hash); }; }, - setConfiguration: confObj => { + setConfiguration: confObj => { for (const [key, value] of Object.entries(confObj)) { switch (key) { - case NAME : navigationModel.setWebsiteName(value); break; - case LOGO : navigationModel.setWebsiteLogo(value); break; - case FAVICON : navigationModel.setFavIcon (value); break; - case HOMEPAGE : navigationModel.setHomeLocation (Location(value)); break; - case DEBUGMODE : navigationModel.setDebugMode (value); break; + case NAME : navigationModel.setWebsiteName (value); break; + case LOGO : navigationModel.setWebsiteLogo (value); break; + case FAVICON : navigationModel.setFavIcon (value); break; + case HOMEPAGE : navigationModel.setHomeLocation (value); break; + case DEBUGMODE : navigationModel.setDebugMode (value); break; default: console.error("can't find key " + key); } } return true; }, - setWebsiteName: navigationModel.setWebsiteName, - getWebsiteName: navigationModel.getWebsiteName, - setWebsiteLogo: navigationModel.setWebsiteLogo, - getWebsiteLogo: navigationModel.getWebsiteLogo, - setFavIcon: navigationModel.setFavIcon, - getFavIcon: navigationModel.getFavIcon, - setHomeLocation: navigationModel.setHomeLocation, - setHomeHash: hash => navigationModel.setHomeLocation(navigationModel.findLocationByHash(hash)), - getHomeLocation: navigationModel.getHomeLocation, - setDebugMode: navigationModel.setDebugMode, - isDebugMode: navigationModel.isDebugMode, - setPath: (val) => console.error(" "+val), - getPath: (val) => console.error(" "+val), - onNavigationHashAdd: navigationModel.onLocationAdded, - onNavigationHashDel: navigationModel.onLocationRemoved, - onLocationChanged: (val) => console.error(" "+val), - onPathChanged: (val) => console.error(" "+val), - onWebsiteNameChanged: navigationModel.onWebsiteNameChanged, + setWebsiteName: navigationModel.setWebsiteName, + getWebsiteName: navigationModel.getWebsiteName, + setWebsiteLogo: navigationModel.setWebsiteLogo, + getWebsiteLogo: navigationModel.getWebsiteLogo, + setFavIcon: navigationModel.setFavIcon, + getFavIcon: navigationModel.getFavIcon, + setHomeLocation: navigationModel.setHomeLocation, + setHomeLocationByHash: setHomeLocationByHash, + getHomeLocation: navigationModel.getHomeLocation, + setDebugMode: navigationModel.setDebugMode, + isDebugMode: navigationModel.isDebugMode, + setPath: (val) => console.error(" "+val), + getPath: (val) => console.error(" "+val), + onLocationAdded: navigationModel.onLocationAdded, + onLocationRemoved: navigationModel.onLocationRemoved, + onLocationChanged: (val) => console.error(" "+val), + onPathChanged: (val) => console.error(" "+val), + onWebsiteNameChanged: navigationModel.onWebsiteNameChanged, onWebsiteLogoChanged: navigationModel.onWebsiteLogoChanged, - onFavIconChanged: navigationModel.onFavIconChanged, - onDebugModeChanged: navigationModel.onDebugModeChanged, - onVisibleChanged: navigationModel.onVisibleChanged, + onFavIconChanged: navigationModel.onFavIconChanged, + onDebugModeChanged: navigationModel.onDebugModeChanged, } }; diff --git a/docs/src/kolibri/navigation/navigationControllerTest.js b/docs/src/kolibri/navigation/navigationControllerTest.js index 628513d0..c12f1880 100644 --- a/docs/src/kolibri/navigation/navigationControllerTest.js +++ b/docs/src/kolibri/navigation/navigationControllerTest.js @@ -35,9 +35,9 @@ navigationSuite.add('setHomeLocation', assert => { assert.is(navigationController.getHomeLocation(), NO_SUCH_LOCATION); - navigationController.setHomeHash(homePageController.getHash()); + navigationController.setHomeLocationByHash(homePageController.getHash()); - assert.is(navigationController.getHomeLocation().hash, '#home'); + assert.is(navigationController.getHomeLocation().getHash(), '#home'); }); navigationSuite.add('onNavigationHashAddAndDel', assert => { @@ -46,8 +46,8 @@ navigationSuite.add('onNavigationHashAddAndDel', assert => { let newHash; let isDeleted = false; - navigationController.onNavigationHashAdd(location => newHash = location.hash); - navigationController.onNavigationHashDel(() => isDeleted = true); + navigationController.onLocationAdded(location => newHash = location.getHash()); + navigationController.onLocationRemoved(() => isDeleted = true); navigationController.addPageControllers(homePageController); @@ -107,7 +107,7 @@ navigationSuite.add('setConfiguration', assert => { assert.is(navigationController.getWebsiteName(), "TestName"); assert.is(navigationController.getWebsiteLogo(), "./logo/kolibri.png"); assert.is(navigationController.getFavIcon(), "./favicon/kolibri.png"); - assert.is(navigationController.getHomeLocation().pageController, homePageController); + assert.is(navigationController.getHomeLocation(), homePageController); assert.is(navigationController.isDebugMode(), true); }); diff --git a/docs/src/kolibri/navigation/navigationModel.js b/docs/src/kolibri/navigation/navigationModel.js index c2698ca9..d9aa1cad 100644 --- a/docs/src/kolibri/navigation/navigationModel.js +++ b/docs/src/kolibri/navigation/navigationModel.js @@ -1,25 +1,26 @@ import { Observable, ObservableList } from "../observable.js"; -export { NavigationModel, Location , NO_SUCH_LOCATION} +export { NavigationModel, NO_SUCH_LOCATION} /** - * @typedef LocationType - * @property { String } hash - starts with hash sign - * @property { PageControllerType } pageController - controller that handles this hash + * @typedef { PageControllerType } LocationType + * This is a type alias for places where a page controller is used to reference a location in the sitemap. */ -// todo: when and how the hash sign is needed should be simplified -const Location = pageController => ({hash: pageController.getHash(), pageController: pageController}); - /** @type { LocationType } */ -const NO_SUCH_LOCATION = undefined; +const NO_SUCH_LOCATION = undefined; /** - * NavigationModelType is the Model that contains the navigation-data for the overall application. - * The model holds the page hashes of the accessible pages, the homepage, the website name, and the website logo. + * NavigationModelType stores the navigation-data for the overall application: + * all accessible locations, + * which of the locations is considered the homepage, + * which of the locations is currently active, + * the website name, favicon, and the website logo. + * * @typedef NavigationModelType - * @property { (pageHash: !String) => void } addLocation - adds the hash of a page, calling all registered {@link ConsumerType}s. - * @property { (pageHash: !String) => void } removeLocation - deletes the hash of a page, calling all registered {@link ConsumerType}s. + * @property { (location: !LocationType) => void } addLocation - + * @property { (location: !LocationType) => void } removeLocation - + * @property { (pageHash: !String) => void } removeLocationByHash - * @property { (cb: ConsumerType) => Boolean } onLocationAdded - registers an {@link ConsumerType} that will be called whenever a page hash is added. * @property { (cb: ConsumerType) => Boolean } onLocationRemoved - registers an {@link ConsumerType} that will be called whenever a page hash is deleted. * @property { (newHomepage: !LocationType) => void } setHomeLocation - sets the given PageController as the homepage. the homepage is the fallback page which gets opened when no hash is provided in the request url. Calling all registered {@link ValueChangeCallback}s. @@ -32,15 +33,16 @@ const NO_SUCH_LOCATION = undefined; * @property { () => String } getWebsiteLogo - returns the path to the website logo. See {@link setWebsiteLogo} * @property { (favIconSrcPath: String) => void } setFavIcon - sets the favicon, calling all registered {@link ValueChangeCallback}s. The favicon path can be set with a {@link NavigationProjectorType} in the index.html. * @property { () => String } getFavIcon - returns the path to the favicon. See {@link setFavIcon} for more details. + * @property { () => LocationType } getCurrentLocation - + * @property { (newLocation: LocationType) => void } setCurrentLocation - + * @property { (cb: ValueChangeCallback) => void } onCurrentLocationChanged - * @property { (cb: ValueChangeCallback) => void } onWebsiteNameChanged - registers an {@link ValueChangeCallback} that will be called whenever the page name changes. * @property { (cb: ValueChangeCallback) => void } onWebsiteLogoChanged - registers an {@link ValueChangeCallback} that will be called whenever the page logo changes. * @property { (cb: ValueChangeCallback) => void } onFavIconChanged - registers an {@link ValueChangeCallback} that will be called whenever the fav icon changes. - * @property { (cb: ValueChangeCallback) => void } onHomeLocationChanged - registers an {@link ValueChangeCallback} that will be called whenever the homepage changes. + * @property { (cb: ValueChangeCallback) => void } onHomeLocationChanged - registers an {@link ValueChangeCallback} that will be called whenever the homepage changes. * @property { (cb: ValueChangeCallback) => void } onDebugModeChanged - registers an {@link ValueChangeCallback} that will be called whenever the debug mode changes. - * @property { (cb: ValueChangeCallback) => void } onVisibleChanged - registers an {@link ValueChangeCallback} that will be called whenever a pages visibility changes. - * @property { (hash: String ) => LocationType } findLocationByHash - + * @property { (hash: String ) => ?LocationType } findLocationByHash - returns location or {@link NO_SUCH_LOCATION} if not found. */ - /** * Constructor for a NavigationModelType. * @return { NavigationModelType } @@ -62,21 +64,18 @@ const NavigationModel = () => { const faviconObs = Observable(''); const websiteNameObs = Observable(''); const websiteLogoObs = Observable(''); - const visibleObs = Observable(true); /** @type { IObservable } */ - const currentLocationObs = Observable(undefined); + const currentLocationObs = Observable(NO_SUCH_LOCATION); const findLocationByHash = hash => locationList.find( location => { - console.log( "hash", location.hash ); // todo: remove - return location.hash === hash; + return location.getHash() === hash; }); - - return /** @type { NavigationModelType } */ { addLocation: locations.add, - removeLocation: hash => locations.del(findLocationByHash(hash)), + removeLocation: locations.del, + removeLocationByHash: hash => locations.del(findLocationByHash(hash)), onLocationAdded: locations.onAdd, onLocationRemoved: locations.onDel, @@ -100,8 +99,6 @@ const NavigationModel = () => { isDebugMode: debugModeObs.getValue, onDebugModeChanged: debugModeObs.onChange, - onVisibleChanged: visibleObs.onChange, // todo: how can this ever be called when the setter is not exposed? - setCurrentLocation: currentLocationObs.setValue, getCurrentLocation: currentLocationObs.getValue, onCurrentLocationChanged: currentLocationObs.onChange, diff --git a/docs/src/kolibri/navigation/projector/basicNavigationProjector.js b/docs/src/kolibri/navigation/projector/basicNavigationProjector.js index 423a119e..2d70d105 100644 --- a/docs/src/kolibri/navigation/projector/basicNavigationProjector.js +++ b/docs/src/kolibri/navigation/projector/basicNavigationProjector.js @@ -38,7 +38,8 @@ const NavigationProjector = (controller, pinToElement) => { navigationAnchors.push(anchor); }); - controller.onNavigationHashAdd(hash => { + controller.onLocationAdded(location => { + const hash = location.getHash(); const newNavPoint = document.createElement('a'); newNavPoint.setAttribute('href', hash); newNavPoint.innerText = hash.substring(1); diff --git a/docs/src/kolibri/navigation/projector/breadcrumb/breadCrumbProjector.js b/docs/src/kolibri/navigation/projector/breadcrumb/breadCrumbProjector.js index 0684960b..5e429410 100644 --- a/docs/src/kolibri/navigation/projector/breadcrumb/breadCrumbProjector.js +++ b/docs/src/kolibri/navigation/projector/breadcrumb/breadCrumbProjector.js @@ -1,5 +1,5 @@ -import { ObservableList } from "../../../kolibri/observable.js"; -import { dom } from "../../../kolibri/util/dom.js"; +import { ObservableList } from "../../../observable.js"; +import { dom } from "../../../util/dom.js"; export { BreadCrumbProjector } diff --git a/docs/src/kolibri/navigation/projector/bubble/bubbleNavigationProjector.js b/docs/src/kolibri/navigation/projector/bubble/bubbleNavigationProjector.js index 67f94d51..432c0663 100644 --- a/docs/src/kolibri/navigation/projector/bubble/bubbleNavigationProjector.js +++ b/docs/src/kolibri/navigation/projector/bubble/bubbleNavigationProjector.js @@ -1,5 +1,5 @@ -import { ObservableList } from "../../../kolibri/observable.js"; -import { dom } from "../../../kolibri/util/dom.js"; +import { ObservableList } from "../../../observable.js"; +import { dom } from "../../../util/dom.js"; export { NavigationProjector as BubbleStateNavigationProjector } diff --git a/docs/src/kolibri/navigation/projector/card/cardNavigationProjector.js b/docs/src/kolibri/navigation/projector/card/cardNavigationProjector.js index 793c1bd9..5036ad24 100644 --- a/docs/src/kolibri/navigation/projector/card/cardNavigationProjector.js +++ b/docs/src/kolibri/navigation/projector/card/cardNavigationProjector.js @@ -1,5 +1,5 @@ -import { ObservableList } from "../../../kolibri/observable.js"; -import { dom } from "../../../kolibri/util/dom.js"; +import { ObservableList } from "../../../observable.js"; +import { dom } from "../../../util/dom.js"; import { GridProjector } from "../util/gridProjector.js"; export { NavigationProjector as CardNavigationProjector } diff --git a/docs/src/kolibri/navigation/projector/dashboard/dashboardNavigationProjector.css b/docs/src/kolibri/navigation/projector/dashboard/dashboardNavigationProjector.css index 0ab1fc2d..e7db5705 100644 --- a/docs/src/kolibri/navigation/projector/dashboard/dashboardNavigationProjector.css +++ b/docs/src/kolibri/navigation/projector/dashboard/dashboardNavigationProjector.css @@ -21,35 +21,37 @@ position: fixed; top: 0; left: 0; - min-height: 100vh; + min-height: calc(100vh - 1/4 * var(--base-unit)); background-color: transparent; display: grid; - grid-template-columns: var(--base-unit); + grid-template-columns: calc(3/2 * var(--base-unit)); font-family: var(--kb-font-rubik-light-regular); - z-index: 1; + margin: calc(1/8 * var(--base-unit)); + box-shadow: 2px 0 4px #dbd7db; + border-radius: calc(1/6 * var(--base-unit)); } .dashboard-refined-nav.open{ - grid-template-columns: var(--base-unit) var(--detail-width); + grid-template-columns: calc(3/2 * var(--base-unit)) var(--detail-width); } .dashboard-refined-nav .overview { min-height: 100%; /*background-color: var(--kb-color-hsl-bg-light);*/ - background-color: #F7F7FC; + background-color: var(--kb-color-hsl-lavender-200); display: flex; flex-direction: column; align-items: center; - border-radius: 0 calc(1/6 * var(--base-unit)) calc(1/6 * var(--base-unit)) 0; + border-radius: calc(1/6 * var(--base-unit)); } .dashboard-refined-nav.open .overview { - border-radius: 0; + border-radius: calc(1/6 * var(--base-unit)) 0 0 calc(1/6 * var(--base-unit)); } .dashboard-refined-nav .overview .logo { - padding-top: var(--std-padding) ; - padding-bottom: var(--std-padding); + padding-top: calc(1/2 * var(--base-unit)); + padding-bottom: var(--base-unit); } .dashboard-refined-nav .overview .logo img { @@ -61,22 +63,18 @@ margin-bottom: calc(2 * var(--std-padding)); } -.dashboard-refined-nav .invisible { - display: none; -} - .dashboard-refined-nav .overview .content .row img { height: calc(4/9 * var(--base-unit)); aspect-ratio: 1; - filter: invert(92%) sepia(11%) saturate(202%) hue-rotate(196deg) brightness(92%) contrast(98%); + filter: invert(27%) sepia(12%) saturate(1127%) hue-rotate(207deg) brightness(98%) contrast(84%); } .dashboard-refined-nav .overview .content .row img.active { - filter: invert(9%) sepia(99%) saturate(6728%) hue-rotate(266deg) brightness(103%) contrast(125%); /* convert svg color to --kb-color-hsl-primary-accent */ + filter: invert(25%) sepia(97%) saturate(7429%) hue-rotate(275deg) brightness(94%) contrast(100%); } .dashboard-refined-nav .overview .content .row img:hover { - filter: invert(51%) sepia(76%) saturate(6321%) hue-rotate(306deg) brightness(100%) contrast(105%); /* convert svg color to --kb-color-hsl-pink-500 */ + filter: invert(51%) sepia(76%) saturate(6321%) hue-rotate(306deg) brightness(100%) contrast(105%); } .dashboard-refined-nav.open .overview .content .row img { @@ -87,12 +85,12 @@ min-height: calc(1/2 * var(--base-unit)); min-width: calc(1/2 * var(--base-unit)); position: absolute; - bottom: var(--std-padding); + bottom: calc(1/2 * var(--base-unit)); display: flex; justify-content: center; align-items: center; border-radius: var(--base-unit); - background-color: #EBECFE; + background-color: #A0A3BD; /*background-color: var(--kb-hsla-primary-bg);*/ } @@ -115,15 +113,17 @@ .dashboard-refined-nav.open .detail { display: block; min-height: 100%; - background-color: #EBECFE; + background-color: var(--kb-color-hsl-purple-100); + /*background-color: var(--kb-hsla-primary-bg);*/ border-radius: 0 calc(1/6 * var(--base-unit)) calc(1/6 * var(--base-unit)) 0; } .dashboard-refined-nav .detail .header { height: var(--header-height); - padding-top: var(--std-padding); + padding-top: calc(1/2 * var(--base-unit)); padding-bottom: var(--std-padding); - padding-left: var(--std-padding); + padding-left: calc(1/3 * var(--base-unit)); + margin-bottom: calc(var(--base-unit) - calc( 9/8 * var(--std-padding))); display: flex; flex-direction: column; justify-content: center; @@ -135,106 +135,62 @@ margin-bottom: calc(3/5 * var(--base-unit)); } -/* Wrapper */ -.dashboard-refined-nav .tree { - display: flex; - flex-direction: column; - padding-left: calc(2/9 * var(--base-unit)); - padding-right: calc(2/9 * var(--base-unit)); - overflow: hidden; -} - -/* Root Nodes */ -.dashboard-refined-nav .tree > .tree-node { - margin-bottom: calc(3/5 * var(--base-unit)) -} - -.dashboard-refined-nav .tree > .tree-node.invisible { - display: none; +.dashboard-refined-nav .detail .content .row { + margin-bottom: calc(1/20 * var(--base-unit)); + padding-left: calc(1/2 * var(--base-unit)); } -.dashboard-refined-nav .tree > .tree-node > span { +.dashboard-refined-nav .detail .content .node { display: flex; + flex-wrap: wrap; align-items: center; gap: 0 1em; - margin-bottom: calc(1/5 * var(--base-unit)); - text-transform: uppercase; - font-size: var(--font-size-textM); - color: var(--kolibri--light---black--200); -} - -.dashboard-refined-nav .tree > .tree-node > span > a { - font-size: var(--font-size-textM); - letter-spacing: 0.01em; - text-decoration: none; - overflow: hidden; - text-overflow: ellipsis; - color: var(--kolibri--light---black--200); - pointer-events: none; } -.dashboard-refined-nav .tree > .tree-node > span > img { +.dashboard-refined-nav .detail .content .row img { height: calc(2/5 * var(--base-unit)); aspect-ratio: 1; + filter: invert(27%) sepia(12%) saturate(1127%) hue-rotate(207deg) brightness(98%) contrast(84%); } -.dashboard-refined-nav .tree > .tree-node > span > img.active { - filter: invert(9%) sepia(99%) saturate(6728%) hue-rotate(266deg) brightness(103%) contrast(125%); /* convert svg color to --kb-color-hsl-primary-accent */ -} - -/* Child Nodes */ -.dashboard-refined-nav .tree-node > .tree-node { - margin-left: calc(2/5 * var(--base-unit)); +.dashboard-refined-nav .detail .content .row svg { + width: calc(2/5 * var(--base-unit)); + height: calc(2/5 * var(--base-unit)); + visibility: hidden; } -.dashboard-refined-nav .tree-node > .tree-node.invisible { - display: none; +.dashboard-refined-nav .detail .content .row.root img.active { + filter: invert(25%) sepia(97%) saturate(7429%) hue-rotate(275deg) brightness(94%) contrast(100%); /* convert svg color to --kb-color-hsl-primary-accent */ } -.dashboard-refined-nav .tree > .tree-node > .tree-node { - margin-left: 0; +.dashboard-refined-nav .detail .content .row a.active { + font-style: var(--kb-font-rubik-light-medium); + font-weight: 600; + color: var(--kb-color-hsl-pink-500); } -.dashboard-refined-nav .tree-node > .tree-node > span { +.dashboard-refined-nav .detail .content .row.root { + margin-bottom: calc(1/5 * var(--base-unit)); display: flex; + flex-wrap: wrap; align-items: center; gap: 0 1em; - margin-bottom: calc(1/20 * var(--base-unit)); -} - -.dashboard-refined-nav .tree-node > .tree-node > span > img { - filter: invert(80%) sepia(10%) saturate(568%) hue-rotate(196deg) brightness(81%) contrast(88%); /* convert svg color to --kb--light--black-500 */ - width: calc(2/5 * var(--base-unit)); - height: calc(2/5 * var(--base-unit)); } -.dashboard-refined-nav .tree-node > .tree-node > span > img.active { - filter: invert(9%) sepia(99%) saturate(6728%) hue-rotate(266deg) brightness(103%) contrast(125%); /* convert svg color to --kb-color-hsl-primary-accent */ +.dashboard-refined-nav .detail .content .row.root span { + text-transform: uppercase; + font-size: var(--font-size-textM); + color: var(--kolibri--light---black--200); } -.dashboard-refined-nav .tree-node > .tree-node > span > a { +.dashboard-refined-nav .detail .content .row a { font-size: var(--font-size-textM); letter-spacing: 0.01em; text-decoration: none; - overflow: hidden; - text-overflow: ellipsis; color: var(--kolibri--light---black--500); } -.dashboard-refined-nav .tree-node > .tree-node > span > a.active { - font-style: var(--kb-font-rubik-light-medium); +.dashboard-refined-nav .detail .content .row a:hover { color: var(--kb-color-hsl-bg-dark); } -.dashboard-refined-nav .tree-node > .tree-node > span > a:hover { - color: var(--kb-color-hsl-pink-500); -} - -.dashboard-refined-nav .tree > div.tree-node:not(:has(div.tree-node)){ - display: none; -} - -.dashboard-refined-nav .tree > div.tree-node:has( > :nth-child(2)#debug-node) { - display: none; -} - diff --git a/docs/src/kolibri/navigation/projector/dashboard/dashboardNavigationProjector.js b/docs/src/kolibri/navigation/projector/dashboard/dashboardNavigationProjector.js index 47aa05c6..6bfc3abd 100644 --- a/docs/src/kolibri/navigation/projector/dashboard/dashboardNavigationProjector.js +++ b/docs/src/kolibri/navigation/projector/dashboard/dashboardNavigationProjector.js @@ -1,5 +1,5 @@ -import { ObservableList } from "../../../kolibri/observable.js"; -import { dom } from "../../../kolibri/util/dom.js"; +import { ObservableList } from "../../../observable.js"; +import { dom } from "../../../util/dom.js"; export { NavigationProjector as DashboardRefinedProjector } @@ -24,14 +24,14 @@ const NavigationProjector = (controller, pinToElement) => { // ************** Create overview and detail wrapper ******************* - const arrowSVGPathRelativeIndex = "../navigation/icons/right-arrow-gradient.svg"; + const arrowSVGPathRelativeIndex = "../../../img/icons/right-arrow-gradient.svg"; const [overviewWrapper, overviewLogo, overviewContentWrapper, overviewToggle] = dom(`
- @@ -316,7 +316,8 @@ const NavigationProjector = (controller, pinToElement) => { } }); - controller.onNavigationHashAdd(hash => { + controller.onLocationAdded( location => { + const hash = location.getHash(); const pageController = controller.getPageController(hash); const qualifier = pageController.getQualifier(); diff --git a/docs/src/kolibri/navigation/projector/dashboard/dashboardNavigationProjector2.css b/docs/src/kolibri/navigation/projector/dashboard/dashboardNavigationProjector2.css deleted file mode 100644 index e7db5705..00000000 --- a/docs/src/kolibri/navigation/projector/dashboard/dashboardNavigationProjector2.css +++ /dev/null @@ -1,196 +0,0 @@ -* { - --kolibri--light---black--900: hsla(0, 0%, 98.8%, 1); - --kolibri--light---black--800: hsla(240, 45.5%, 97.8%, 1); - --kolibri--light---black--600: hsla(233, 26.7%, 88.2%, 1); - --kolibri--light---black--700: hsla(231, 28%, 95.1%, 1); - --kolibri--light---black--500: hsla(234, 18%, 68.4%, 1); - --kolibri--light---black--400: hsla(235, 13.7%, 50%, 1); - --kolibri--light---black--300: hsla(247, 15.3%, 34.7%, 1); - --kolibri--light---black--200: hsla(249, 23.1%, 17.8%, 1); - --kolibri--light---black--100: hsla(240, 35.5%, 12.2%, 1); - - box-sizing: border-box; -} - -.dashboard-refined-nav { - --base-unit: 4em; - /*--detail-width: 0;*/ - --detail-width: calc( 4 * var(--base-unit)); - --header-height: calc(4/5 * var(--base-unit)); - --std-padding: calc(1/5 * var(--base-unit)); - position: fixed; - top: 0; - left: 0; - min-height: calc(100vh - 1/4 * var(--base-unit)); - background-color: transparent; - display: grid; - grid-template-columns: calc(3/2 * var(--base-unit)); - font-family: var(--kb-font-rubik-light-regular); - margin: calc(1/8 * var(--base-unit)); - box-shadow: 2px 0 4px #dbd7db; - border-radius: calc(1/6 * var(--base-unit)); -} - -.dashboard-refined-nav.open{ - grid-template-columns: calc(3/2 * var(--base-unit)) var(--detail-width); -} - -.dashboard-refined-nav .overview { - min-height: 100%; - /*background-color: var(--kb-color-hsl-bg-light);*/ - background-color: var(--kb-color-hsl-lavender-200); - display: flex; - flex-direction: column; - align-items: center; - border-radius: calc(1/6 * var(--base-unit)); -} - -.dashboard-refined-nav.open .overview { - border-radius: calc(1/6 * var(--base-unit)) 0 0 calc(1/6 * var(--base-unit)); -} - -.dashboard-refined-nav .overview .logo { - padding-top: calc(1/2 * var(--base-unit)); - padding-bottom: var(--base-unit); -} - -.dashboard-refined-nav .overview .logo img { - height: var(--header-height); - aspect-ratio: 1; -} - -.dashboard-refined-nav .overview .content .row { - margin-bottom: calc(2 * var(--std-padding)); -} - -.dashboard-refined-nav .overview .content .row img { - height: calc(4/9 * var(--base-unit)); - aspect-ratio: 1; - filter: invert(27%) sepia(12%) saturate(1127%) hue-rotate(207deg) brightness(98%) contrast(84%); -} - -.dashboard-refined-nav .overview .content .row img.active { - filter: invert(25%) sepia(97%) saturate(7429%) hue-rotate(275deg) brightness(94%) contrast(100%); -} - -.dashboard-refined-nav .overview .content .row img:hover { - filter: invert(51%) sepia(76%) saturate(6321%) hue-rotate(306deg) brightness(100%) contrast(105%); -} - -.dashboard-refined-nav.open .overview .content .row img { - display: none; -} - -.dashboard-refined-nav .overview .toggle { - min-height: calc(1/2 * var(--base-unit)); - min-width: calc(1/2 * var(--base-unit)); - position: absolute; - bottom: calc(1/2 * var(--base-unit)); - display: flex; - justify-content: center; - align-items: center; - border-radius: var(--base-unit); - background-color: #A0A3BD; - /*background-color: var(--kb-hsla-primary-bg);*/ -} - -.dashboard-refined-nav .overview .toggle img { - height: calc(9/20 * var(--base-unit)); - aspect-ratio: 1; - transition: 0.2s; - cursor: pointer; -} - -.dashboard-refined-nav.open .overview .toggle img { - transform: rotate(180deg); - transition: 0.2s; -} - -.dashboard-refined-nav .detail { - display: none; -} - -.dashboard-refined-nav.open .detail { - display: block; - min-height: 100%; - background-color: var(--kb-color-hsl-purple-100); - /*background-color: var(--kb-hsla-primary-bg);*/ - border-radius: 0 calc(1/6 * var(--base-unit)) calc(1/6 * var(--base-unit)) 0; -} - -.dashboard-refined-nav .detail .header { - height: var(--header-height); - padding-top: calc(1/2 * var(--base-unit)); - padding-bottom: var(--std-padding); - padding-left: calc(1/3 * var(--base-unit)); - margin-bottom: calc(var(--base-unit) - calc( 9/8 * var(--std-padding))); - display: flex; - flex-direction: column; - justify-content: center; - font-size: var(--font-size-h5); - color: var(--kolibri--light---black--200); -} - -.dashboard-refined-nav .detail .content { - margin-bottom: calc(3/5 * var(--base-unit)); -} - -.dashboard-refined-nav .detail .content .row { - margin-bottom: calc(1/20 * var(--base-unit)); - padding-left: calc(1/2 * var(--base-unit)); -} - -.dashboard-refined-nav .detail .content .node { - display: flex; - flex-wrap: wrap; - align-items: center; - gap: 0 1em; -} - -.dashboard-refined-nav .detail .content .row img { - height: calc(2/5 * var(--base-unit)); - aspect-ratio: 1; - filter: invert(27%) sepia(12%) saturate(1127%) hue-rotate(207deg) brightness(98%) contrast(84%); -} - -.dashboard-refined-nav .detail .content .row svg { - width: calc(2/5 * var(--base-unit)); - height: calc(2/5 * var(--base-unit)); - visibility: hidden; -} - -.dashboard-refined-nav .detail .content .row.root img.active { - filter: invert(25%) sepia(97%) saturate(7429%) hue-rotate(275deg) brightness(94%) contrast(100%); /* convert svg color to --kb-color-hsl-primary-accent */ -} - -.dashboard-refined-nav .detail .content .row a.active { - font-style: var(--kb-font-rubik-light-medium); - font-weight: 600; - color: var(--kb-color-hsl-pink-500); -} - -.dashboard-refined-nav .detail .content .row.root { - margin-bottom: calc(1/5 * var(--base-unit)); - display: flex; - flex-wrap: wrap; - align-items: center; - gap: 0 1em; -} - -.dashboard-refined-nav .detail .content .row.root span { - text-transform: uppercase; - font-size: var(--font-size-textM); - color: var(--kolibri--light---black--200); -} - -.dashboard-refined-nav .detail .content .row a { - font-size: var(--font-size-textM); - letter-spacing: 0.01em; - text-decoration: none; - color: var(--kolibri--light---black--500); -} - -.dashboard-refined-nav .detail .content .row a:hover { - color: var(--kb-color-hsl-bg-dark); -} - diff --git a/docs/src/kolibri/navigation/projector/flower/flowerNavigationProjector.js b/docs/src/kolibri/navigation/projector/flower/flowerNavigationProjector.js index 2bcb39c8..98c144bd 100644 --- a/docs/src/kolibri/navigation/projector/flower/flowerNavigationProjector.js +++ b/docs/src/kolibri/navigation/projector/flower/flowerNavigationProjector.js @@ -1,5 +1,5 @@ -import { ObservableList } from "../../../kolibri/observable.js"; -import { dom } from "../../../kolibri/util/dom.js"; +import { ObservableList } from "../../../observable.js"; +import { dom } from "../../../util/dom.js"; export { NavigationProjector as FlowerNavigationProjector } diff --git a/docs/src/kolibri/navigation/projector/navigation.css b/docs/src/kolibri/navigation/projector/navigation.css index eb44fb67..df99eee9 100644 --- a/docs/src/kolibri/navigation/projector/navigation.css +++ b/docs/src/kolibri/navigation/projector/navigation.css @@ -1,8 +1,7 @@ -@import "docs/src/kolibri/navigation/projector/breadcrumb/breadCrumbProjector.css"; -@import "docs/src/kolibri/navigation/projector/bubble/bubbleNavigationProjector.css"; -@import "docs/src/examples/navigation/menue/dashboard/dashboardNavigationProjector.css"; -@import "docs/src/kolibri/navigation/projector/dashboard/dashboardNavigationProjector.css"; -@import "docs/src/kolibri/navigation/projector/card/cardNavigationProjector.css"; -@import "docs/src/kolibri/navigation/projector/flower/flowerNavigationProjector.css"; -@import "docs/src/kolibri/navigation/projector/pageSwitch/pageSwitchProjector.css"; -@import "docs/src/kolibri/navigation/projector/pageSwitch/github-gists-styles.css"; +@import "../../../../../docs/src/kolibri/navigation/projector/breadcrumb/breadCrumbProjector.css"; +@import "../../../../../docs/src/kolibri/navigation/projector/bubble/bubbleNavigationProjector.css"; +@import "../../../../../docs/src/kolibri/navigation/projector/dashboard/dashboardNavigationProjector.css"; +@import "../../../../../docs/src/kolibri/navigation/projector/card/cardNavigationProjector.css"; +@import "../../../../../docs/src/kolibri/navigation/projector/flower/flowerNavigationProjector.css"; +@import "../../../../../docs/src/kolibri/navigation/projector/pageSwitch/pageSwitchProjector.css"; +@import "../../../../../docs/src/kolibri/navigation/projector/pageSwitch/github-gists-styles.css"; diff --git a/docs/src/kolibri/navigation/projector/page/debugPage/debugPageProjector.js b/docs/src/kolibri/navigation/projector/page/debugPage/debugPageProjector.js index 3c847b3d..bc2f86f6 100644 --- a/docs/src/kolibri/navigation/projector/page/debugPage/debugPageProjector.js +++ b/docs/src/kolibri/navigation/projector/page/debugPage/debugPageProjector.js @@ -1,4 +1,4 @@ -import { dom } from "../../kolibri/util/dom.js"; +import { dom } from "../../../../util/dom.js"; export { DebugPageProjector } diff --git a/docs/src/kolibri/navigation/projector/pageSwitch/pageSwitchProjector.js b/docs/src/kolibri/navigation/projector/pageSwitch/pageSwitchProjector.js index c1a44461..8bc1ce8f 100644 --- a/docs/src/kolibri/navigation/projector/pageSwitch/pageSwitchProjector.js +++ b/docs/src/kolibri/navigation/projector/pageSwitch/pageSwitchProjector.js @@ -1,5 +1,5 @@ -import { ObservableList } from "../../../kolibri/observable.js"; -import { dom } from "../../../kolibri/util/dom.js"; +import { ObservableList } from "../../../observable.js"; +import { dom } from "../../../util/dom.js"; export { PageSwitchProjector } diff --git a/docs/src/kolibri/navigation/projector/util/navigationProjectorTemplate.js b/docs/src/kolibri/navigation/projector/util/navigationProjectorTemplate.js index 516012c0..41291f76 100644 --- a/docs/src/kolibri/navigation/projector/util/navigationProjectorTemplate.js +++ b/docs/src/kolibri/navigation/projector/util/navigationProjectorTemplate.js @@ -1,5 +1,5 @@ -import { ObservableList } from "../kolibri/observable.js"; -import { dom } from "../kolibri/util/dom.js"; +import { ObservableList } from "../../../observable.js"; +import { dom } from "../../../util/dom.js"; export { NavigationProjector } @@ -80,10 +80,10 @@ const NavigationProjector = (controller, pinToElement) => { // add favicon to website }); - controller.onNavigationHashAdd(hash => { - const pageController = controller.getPageController(hash); + controller.onLocationAdded( location => { + const pageController = location; const pageName = pageController.getValue(); - const newNavPoint = initializeNavigationPoint(hash, pageName); + const newNavPoint = initializeNavigationPoint(location.getHash(), pageName); observableNavigationAnchors.add(newNavPoint); // CREATE BINDINGS