From 1267d779fe0fb4cf97e14e1661438f8d30e4819b Mon Sep 17 00:00:00 2001 From: Maximiliano Tabacman Date: Wed, 9 Jun 2021 21:09:15 -0300 Subject: [PATCH 1/4] Minor protocol corrections. --- source/RenoirSt-Core/CssColor.class.st | 4 ++-- source/RenoirSt-Core/CssColorUnit.class.st | 4 ++-- source/RenoirSt-Core/CssHSLColor.class.st | 4 ++-- source/RenoirSt-Core/CssRGBColor.class.st | 4 ++-- source/RenoirSt-Tests/CssTypeSelectorTest.class.st | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/source/RenoirSt-Core/CssColor.class.st b/source/RenoirSt-Core/CssColor.class.st index 2de8395..60009fa 100644 --- a/source/RenoirSt-Core/CssColor.class.st +++ b/source/RenoirSt-Core/CssColor.class.st @@ -14,7 +14,7 @@ CssColor >> componentsDo: aBlockClosure separatedBy: aSeparationBlock [ self subclassResponsibility ] -{ #category : #Printing } +{ #category : #printing } CssColor >> cssContentOn: aWriteStream [ aWriteStream nextPutAll: self functionName; @@ -29,7 +29,7 @@ CssColor >> functionName [ self subclassResponsibility ] -{ #category : #Converting } +{ #category : #converting } CssColor >> identifiedBy: aString [ ^CssIdentifiedColor representing: self identifiedBy: aString diff --git a/source/RenoirSt-Core/CssColorUnit.class.st b/source/RenoirSt-Core/CssColorUnit.class.st index 24f3381..51f20f5 100644 --- a/source/RenoirSt-Core/CssColorUnit.class.st +++ b/source/RenoirSt-Core/CssColorUnit.class.st @@ -7,13 +7,13 @@ Class { #category : #'RenoirSt-Core-Colors' } -{ #category : #Converting } +{ #category : #converting } CssColorUnit >> identifiedBy: aString [ self subclassResponsibility ] -{ #category : #Converting } +{ #category : #converting } CssColorUnit >> newWithAlpha: alphaValue [ self subclassResponsibility diff --git a/source/RenoirSt-Core/CssHSLColor.class.st b/source/RenoirSt-Core/CssHSLColor.class.st index a485254..a81526b 100644 --- a/source/RenoirSt-Core/CssHSLColor.class.st +++ b/source/RenoirSt-Core/CssHSLColor.class.st @@ -59,7 +59,7 @@ CssHSLColor >> functionName [ ^ alphaChannel functionNameFor: 'hsl' ] -{ #category : #'initialize-release' } +{ #category : #initialization } CssHSLColor >> initializeHue: aHueValueInDegrees saturation: aSaturationPercentage lightness: aLightnessPercentage alphaChannel: aCssAlphaChannel [ hue := aHueValueInDegrees. @@ -68,7 +68,7 @@ CssHSLColor >> initializeHue: aHueValueInDegrees saturation: aSaturationPercenta alphaChannel := aCssAlphaChannel ] -{ #category : #Converting } +{ #category : #converting } CssHSLColor >> newWithAlpha: alphaValue [ ^ self class diff --git a/source/RenoirSt-Core/CssRGBColor.class.st b/source/RenoirSt-Core/CssRGBColor.class.st index 7aa8ee8..b479d21 100644 --- a/source/RenoirSt-Core/CssRGBColor.class.st +++ b/source/RenoirSt-Core/CssRGBColor.class.st @@ -59,7 +59,7 @@ CssRGBColor >> functionName [ ^ alphaChannel functionNameFor: 'rgb' ] -{ #category : #'initialize-release' } +{ #category : #initialization } CssRGBColor >> initializeRed: aRedComponent green: aGreenComponent blue: aBlueComponent alphaChannel: theAlphaChannelInfo [ redComponent := aRedComponent. @@ -68,7 +68,7 @@ CssRGBColor >> initializeRed: aRedComponent green: aGreenComponent blue: aBlueCo alphaChannel := theAlphaChannelInfo ] -{ #category : #'as yet unclassified' } +{ #category : #converting } CssRGBColor >> newWithAlpha: alphaValue [ ^ self class diff --git a/source/RenoirSt-Tests/CssTypeSelectorTest.class.st b/source/RenoirSt-Tests/CssTypeSelectorTest.class.st index 2e793de..fe9bc92 100644 --- a/source/RenoirSt-Tests/CssTypeSelectorTest.class.st +++ b/source/RenoirSt-Tests/CssTypeSelectorTest.class.st @@ -20,5 +20,5 @@ CssTypeSelectorTest >> testBuildingShortcut [ { #category : #Tests } CssTypeSelectorTest >> testPrintString [ - self assert: (CssTypeSelector ofType: 'h1') printString = 'h1' + self assert: (CssTypeSelector ofType: 'h1') printString equals: 'h1' ] From 4306b9ed968f414095fce2aaa2f21cb91e47f050 Mon Sep 17 00:00:00 2001 From: Gabriel Omar Cotelli Date: Wed, 30 Jun 2021 18:02:31 -0300 Subject: [PATCH 2/4] Use the new build infra --- .github/workflows/build.yml | 24 - .github/workflows/loading-groups.yml | 23 + .github/workflows/markdown-lint.yml | 14 + .github/workflows/unit-tests.yml | 26 + ...loading.deployment-seaside-extensions.ston | 13 + .smalltalkci/.loading.deployment.ston | 13 + ...oading.development-seaside-extensions.ston | 16 + .smalltalkci/.loading.development.ston | 16 + .smalltalkci/.loading.tests.ston | 16 + .smalltalkci/.loading.tools.ston | 13 + .../.unit-tests.ston | 5 +- CONTRIBUTING.md | 32 +- LICENSE | 2 +- README.md | 53 +- docs/Installation.md | 54 +- docs/tutorial/Tutorial-Part-I.md | 619 ++++++++++++------ docs/tutorial/Tutorial-Part-II.md | 215 ++++-- docs/tutorial/Tutorial-Part-III.md | 434 +++++++----- docs/tutorial/Tutorial-TOC.md | 10 +- 19 files changed, 1058 insertions(+), 540 deletions(-) delete mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/loading-groups.yml create mode 100644 .github/workflows/markdown-lint.yml create mode 100644 .github/workflows/unit-tests.yml create mode 100644 .smalltalkci/.loading.deployment-seaside-extensions.ston create mode 100644 .smalltalkci/.loading.deployment.ston create mode 100644 .smalltalkci/.loading.development-seaside-extensions.ston create mode 100644 .smalltalkci/.loading.development.ston create mode 100644 .smalltalkci/.loading.tests.ston create mode 100644 .smalltalkci/.loading.tools.ston rename .smalltalk.ston => .smalltalkci/.unit-tests.ston (69%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index aa74baf..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Build - -on: [push,pull_request] - -jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - smalltalk: [ Pharo64-8.0, Pharo64-7.0, Pharo32-7.0, Pharo32-6.1 ] - name: ${{ matrix.smalltalk }} - steps: - - uses: actions/checkout@v2 - - uses: ba-st-actions/setup-smalltalkCI@v1.0.0 - with: - smalltalk-version: ${{ matrix.smalltalk }} - - run: smalltalkci -s ${{ matrix.smalltalk }} - timeout-minutes: 15 - - run: echo "::set-env name=SCI_COVERAGE_FILE_LOCATION::${HOME}/.smalltalkCI/_builds/coveralls_results.json" - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1.0.6 - with: - token: ${{ secrets.CODECOV_TOKEN }} - file: ${{ env.SCI_COVERAGE_FILE_LOCATION }} diff --git a/.github/workflows/loading-groups.yml b/.github/workflows/loading-groups.yml new file mode 100644 index 0000000..1f9eca6 --- /dev/null +++ b/.github/workflows/loading-groups.yml @@ -0,0 +1,23 @@ +name: Group loading check + +on: [push,pull_request,workflow_dispatch] + +jobs: + group-loading: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + smalltalk: [ Pharo64-9.0, Pharo64-8.0 ] + load-spec: [ deployment, deployment-seaside-extensions, tests, tools, development, development-seaside-extensions ] + name: ${{ matrix.smalltalk }} + ${{ matrix.load-spec }} + steps: + - uses: actions/checkout@v2 + - uses: hpi-swa/setup-smalltalkCI@v1 + with: + smalltalk-image: ${{ matrix.smalltalk }} + - name: Load group in image + run: smalltalkci -s ${{ matrix.smalltalk }} .smalltalkci/.loading.${{ matrix.load-spec }}.ston + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + timeout-minutes: 15 diff --git a/.github/workflows/markdown-lint.yml b/.github/workflows/markdown-lint.yml new file mode 100644 index 0000000..c1f5f49 --- /dev/null +++ b/.github/workflows/markdown-lint.yml @@ -0,0 +1,14 @@ +name: Markdown Lint +on: [pull_request,workflow_dispatch] +jobs: + remark-lint: + name: runner / markdownlint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: markdownlint + uses: reviewdog/action-markdownlint@v0.1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + fail_on_error: true + reporter: github-pr-review diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml new file mode 100644 index 0000000..4812544 --- /dev/null +++ b/.github/workflows/unit-tests.yml @@ -0,0 +1,26 @@ +name: Unit Tests + +on: [push,pull_request,workflow_dispatch] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + smalltalk: [ Pharo64-9.0, Pharo64-8.0, Pharo64-7.0, Pharo32-7.0 ] + name: ${{ matrix.smalltalk }} + steps: + - uses: actions/checkout@v2 + - uses: hpi-swa/setup-smalltalkCI@v1 + with: + smalltalk-image: ${{ matrix.smalltalk }} + - name: Load Image and Run Tests + run: smalltalkci -s ${{ matrix.smalltalk }} .smalltalkci/.unit-tests.ston + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + timeout-minutes: 15 + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v1 + with: + name: ${{matrix.os}}-${{matrix.smalltalk}} + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.smalltalkci/.loading.deployment-seaside-extensions.ston b/.smalltalkci/.loading.deployment-seaside-extensions.ston new file mode 100644 index 0000000..5518b2d --- /dev/null +++ b/.smalltalkci/.loading.deployment-seaside-extensions.ston @@ -0,0 +1,13 @@ +SmalltalkCISpec { + #loading : [ + SCIMetacelloLoadSpec { + #baseline : 'RenoirSt', + #directory : '../source', + #load : [ 'Deployment-Seaside-Extensions' ], + #platforms : [ #pharo ] + } + ], + #testing : { + #failOnZeroTests : false + } +} diff --git a/.smalltalkci/.loading.deployment.ston b/.smalltalkci/.loading.deployment.ston new file mode 100644 index 0000000..42e3fb8 --- /dev/null +++ b/.smalltalkci/.loading.deployment.ston @@ -0,0 +1,13 @@ +SmalltalkCISpec { + #loading : [ + SCIMetacelloLoadSpec { + #baseline : 'RenoirSt', + #directory : '../source', + #load : [ 'Deployment' ], + #platforms : [ #pharo ] + } + ], + #testing : { + #failOnZeroTests : false + } +} diff --git a/.smalltalkci/.loading.development-seaside-extensions.ston b/.smalltalkci/.loading.development-seaside-extensions.ston new file mode 100644 index 0000000..414844e --- /dev/null +++ b/.smalltalkci/.loading.development-seaside-extensions.ston @@ -0,0 +1,16 @@ +SmalltalkCISpec { + #loading : [ + SCIMetacelloLoadSpec { + #baseline : 'RenoirSt', + #directory : '../source', + #load : [ 'Development-Seaside-Extensions' ], + #platforms : [ #pharo ] + } + ], + #testing : { + #coverage : { + #packages : [ 'RenoirSt*' ], + #format: #lcov + } + } +} diff --git a/.smalltalkci/.loading.development.ston b/.smalltalkci/.loading.development.ston new file mode 100644 index 0000000..5dc3d36 --- /dev/null +++ b/.smalltalkci/.loading.development.ston @@ -0,0 +1,16 @@ +SmalltalkCISpec { + #loading : [ + SCIMetacelloLoadSpec { + #baseline : 'RenoirSt', + #directory : '../source', + #load : [ 'Development' ], + #platforms : [ #pharo ] + } + ], + #testing : { + #coverage : { + #packages : [ 'RenoirSt*' ], + #format: #lcov + } + } +} diff --git a/.smalltalkci/.loading.tests.ston b/.smalltalkci/.loading.tests.ston new file mode 100644 index 0000000..998c8fb --- /dev/null +++ b/.smalltalkci/.loading.tests.ston @@ -0,0 +1,16 @@ +SmalltalkCISpec { + #loading : [ + SCIMetacelloLoadSpec { + #baseline : 'RenoirSt', + #directory : '../source', + #load : [ 'Tests' ], + #platforms : [ #pharo ] + } + ], + #testing : { + #coverage : { + #packages : [ 'RenoirSt*' ], + #format: #lcov + } + } +} diff --git a/.smalltalkci/.loading.tools.ston b/.smalltalkci/.loading.tools.ston new file mode 100644 index 0000000..ff1a3c1 --- /dev/null +++ b/.smalltalkci/.loading.tools.ston @@ -0,0 +1,13 @@ +SmalltalkCISpec { + #loading : [ + SCIMetacelloLoadSpec { + #baseline : 'RenoirSt', + #directory : '../source', + #load : [ 'Tools' ], + #platforms : [ #pharo ] + } + ], + #testing : { + #failOnZeroTests : false + } +} diff --git a/.smalltalk.ston b/.smalltalkci/.unit-tests.ston similarity index 69% rename from .smalltalk.ston rename to .smalltalkci/.unit-tests.ston index 7c534a9..4f9843a 100644 --- a/.smalltalk.ston +++ b/.smalltalkci/.unit-tests.ston @@ -2,14 +2,15 @@ SmalltalkCISpec { #loading : [ SCIMetacelloLoadSpec { #baseline : 'RenoirSt', - #directory : 'source', + #directory : '../source', #load : [ 'CI' ], #platforms : [ #pharo ] } ], #testing : { #coverage : { - #packages : [ 'RenoirSt*' ] + #packages : [ 'RenoirSt*' ], + #format: #lcov } } } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f0703ca..395b0ab 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,24 +1,33 @@ -Contributing -============ +# Contributing -There's several ways to contribute to the project: reporting bugs, sending feedback, proposing ideas for new features, fixing or adding documentation, promoting the project, or even contributing code. +There's several ways to contribute to the project: reporting bugs, sending +feedback, proposing ideas for new features, fixing or adding documentation, +promoting the project, or even contributing code. ## Reporting issues You can report issues [here](https://github.com/ba-st/RenoirSt/issues/new) ## Contributing Code + - This project is MIT licensed, so any code contribution MUST be under the same license. -- This project uses [Semantic Versioning](http://semver.org/), so keep it in mind when you make backwards-incompatible changes. If some backwards incompatible change is made the major version MUST be increased. -- The source code is hosted in this repository using the Tonel format in the `source` folder. -- The master branch contains the latest changes and should always be in a releasable state. +- This project uses [Semantic Versioning](http://semver.org/), so keep it in mind + when you make backwards-incompatible changes. If some backwards incompatible + change is made the major version MUST be increased. +- The source code is hosted in this repository using the Tonel format in the + `source` folder. +- The master branch contains the latest changes and should always be in a + releasable state. - Feel free to send pull requests or fork the project. -- Code contributions without test cases have a lower probability of being merged into the main branch. +- Code contributions without test cases have a lower probability of being merged + into the main branch. ### Using Iceberg + 1. Download a [Pharo Image and VM](https://get.pharo.org/64) 2. Clone the project or your fork using Iceberg -3. Open the Working Copy and using the contextual menu select `Metacello -> Install baseline...` +3. Open the Working Copy and using the contextual menu select + `Metacello -> Install baseline...` 4. Input `Development-Seaside-Extensions` 5. This will load the base code and the test cases 6. Create a new branch to host your code changes @@ -29,8 +38,11 @@ You can report issues [here](https://github.com/ba-st/RenoirSt/issues/new) ## Contributing documentation -The project documentation is maintained in this repository in the `docs` folder and licensed under CC BY-SA 4.0. To contribute some documentation or improve the existing, feel free to create a branch or fork this repository, make your changes and send a pull request. +The project documentation is maintained in this repository in the `docs` folder +and licensed under CC BY-SA 4.0. To contribute some documentation or improve the +existing, feel free to create a branch or fork this repository, make your +changes and send a pull request. -### Useful References: +### Useful References - [W3c Css Home](http://www.w3.org/Style/CSS/) diff --git a/LICENSE b/LICENSE index a79cb48..5ca9e0a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2013-2020 Gabriel Cotelli, RenoirSt and Buenos Aires Smalltalk Contributors +Copyright (c) 2013-2021 Gabriel Cotelli, RenoirSt and Buenos Aires Smalltalk Contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 1f7f814..17052f3 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,38 @@ -

-

RenoirSt

-

- A DSL enabling programmatic cascading style sheet generation for Pharo Smalltalk -
- Explore the docs » -
-
- Report a defect - | - Request feature -

-

- -![GitHub release](https://img.shields.io/github/release/ba-st/RenoirSt.svg) -[![Build Status](https://github.com/ba-st/RenoirSt/workflows/Build/badge.svg?branch=release-candidate)](https://github.com/ba-st/RenoirSt/actions?query=workflow%3ABuild) +# RenoirSt + +![Logo](assets/logos/128x128.png) + +A DSL enabling programmatic cascading style sheet generation for Pharo Smalltalk + +[![Unit Tests](https://github.com/ba-st/RenoirSt/actions/workflows/unit-tests.yml/badge.svg)](https://github.com/ba-st/RenoirSt/actions/workflows/unit-tests.yml) [![Coverage Status](https://codecov.io/github/ba-st/RenoirSt/coverage.svg?branch=release-candidate)](https://codecov.io/gh/ba-st/RenoirSt/branch/release-candidate) +[![Group loading check](https://github.com/ba-st/RenoirSt/actions/workflows/loading-groups.yml/badge.svg)](https://github.com/ba-st/RenoirSt/actions/workflows/loading-groups.yml) +[![Markdown Lint](https://github.com/ba-st/RenoirSt/actions/workflows/markdown-lint.yml/badge.svg)](https://github.com/ba-st/RenoirSt/actions/workflows/markdown-lint.yml) + +[![GitHub release](https://img.shields.io/github/release/ba-st/RenoirSt.svg)](https://github.com/ba-st/RenoirSt/releases/latest) [![Pharo 6.1](https://img.shields.io/badge/Pharo-6.1-informational)](https://pharo.org) [![Pharo 7.0](https://img.shields.io/badge/Pharo-7.0-informational)](https://pharo.org) [![Pharo 8.0](https://img.shields.io/badge/Pharo-8.0-informational)](https://pharo.org) +Quick links + +- [**Explore the docs**](docs/) +- [Report a defect](https://github.com/ba-st/RenoirSt/issues/new?labels=Type%3A+Defect) +- [Request a feature](https://github.com/ba-st/RenoirSt/issues/new?labels=Type%3A+Feature) + ## Goals + - Improve CSS integration with existing Web Frameworks - Write & refactor in Smalltalk, deploy to CSS -### Benefits: +### Benefits + - Keep in sync your code changes with the changes in the CSS -- Use your favorite browsing and refactoring tools inside the same Pharo image to handle CSS +- Use your favorite browsing and refactoring tools inside the same Pharo image + to handle CSS ## License + - The code is licensed under [MIT](LICENSE). - The documentation is licensed under [CC BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/). @@ -43,22 +48,24 @@ Now you can try the Hello World: ```smalltalk CascadingStyleSheetBuilder new - declareRuleSetFor: [:selector | selector body before] - with: [:style | style content: '"Hello World"']; - build + declareRuleSetFor: [:selector | selector body before] + with: [:style | style content: '"Hello World"']; + build ``` you should see something like this: + ```css body::before { - content: "Hello World"; + content: "Hello World"; } ``` ## Installation -To load the project in a Pharo image, or declare it as a dependency of your own project follow this [instructions](docs/Installation.md). +To load the project in a Pharo image, or declare it as a dependency of your own +project follow this [instructions](docs/Installation.md). ## Contributing diff --git a/docs/Installation.md b/docs/Installation.md index 5b7fc66..f742d44 100644 --- a/docs/Installation.md +++ b/docs/Installation.md @@ -5,21 +5,23 @@ ### Pharo 6.1 or greater You can load **RenoirSt** evaluating: + ```smalltalk Metacello new - baseline: 'RenoirSt'; - repository: 'github://ba-st/RenoirSt:release-candidate/source'; - load. + baseline: 'RenoirSt'; + repository: 'github://ba-st/RenoirSt:release-candidate/source'; + load. ``` -> Change `release-candidate` to some released version if you want a pinned version + +> Change `release-candidate` to some released version if you want a pinned version or if you want to use the Seaside extensions: ```smalltalk Metacello new - baseline: 'RenoirSt'; - repository: 'github://ba-st/RenoirSt:release-candidate/source'; - load: 'Deployment-Seaside-Extensions'. + baseline: 'RenoirSt'; + repository: 'github://ba-st/RenoirSt:release-candidate/source'; + load: 'Deployment-Seaside-Extensions'. ``` ### Pharo 5 @@ -69,36 +71,42 @@ Gofer it ## Using as dependency -In order to include **RenoirSt** as part of your project, you should reference the package in your product baseline: +In order to include **RenoirSt** as part of your project, you should reference +the package in your product baseline: ```smalltalk setUpDependencies: spec - spec - baseline: 'RenoirSt' - with: [ spec - repository: 'github://ba-st/RenoirSt:v{XX}/source'; - loads: #('Deployment') ]; - import: 'RenoirSt'. + spec + baseline: 'RenoirSt' + with: [ spec + repository: 'github://ba-st/RenoirSt:v{XX}/source'; + loads: #('Deployment') ]; + import: 'RenoirSt'. ``` + > Replace `{XX}` with the version you want to depend on ```smalltalk baseline: spec - - spec - for: #common - do: [ self setUpDependencies: spec. - spec package: 'My-Package' with: [ spec requires: #('RenoirSt') ] ] + + spec + for: #common + do: [ self setUpDependencies: spec. + spec package: 'My-Package' with: [ spec requires: #('RenoirSt') ] ] ``` ## Provided groups - `Deployment` will load all the packages needed in a deployed application - `Tests` will load the test cases -- `Tools` will load the extensions to the SUnit framework and development tools (inspector and spotter extensions) +- `Tools` will load the extensions to the SUnit framework and development tools + (inspector and spotter extensions) - `CI` is the group loaded in the continuous integration setup -- `Development` will load all the needed packages to develop and contribute to the project -- `Deployment-Seaside-Extensions` will load all the packages needed in a deployed application including the Javascript extensions -- `Development-Seaside-Extensions` will load all the needed packages to develop and contribute to the project including the Javascript extensions +- `Development` will load all the needed packages to develop and contribute to + the project +- `Deployment-Seaside-Extensions` will load all the packages needed in a deployed + application including the Javascript extensions +- `Development-Seaside-Extensions` will load all the needed packages to develop + and contribute to the project including the Javascript extensions diff --git a/docs/tutorial/Tutorial-Part-I.md b/docs/tutorial/Tutorial-Part-I.md index 8a929b6..b42cbf0 100644 --- a/docs/tutorial/Tutorial-Part-I.md +++ b/docs/tutorial/Tutorial-Part-I.md @@ -1,17 +1,22 @@ -Tutorial - Part I -================= +# Tutorial - Part I ## Introduction This tutorial asumes some knowledge of CSS and Pharo Smalltalk. -The main entry point for the library is the class `CascadingStyleSheetBuilder`. Let's see some minimalist example. Copy the following in a workspace and `Inspect-it (Alt+i)`: +The main entry point for the library is the class `CascadingStyleSheetBuilder`. +Let's see some minimalist example. Copy the following in a workspace and +`Inspect-it (Alt+i)`: ```smalltalk CascadingStyleSheetBuilder new build ``` -Beautiful! You have now an inspector on your fisrt (empty and useless) style sheet. Let's do something more useful now. Real stylesheets are composed of rules (or rule-sets), where each has a selector and a declaration group. The selector determines if the rule applies to some element in the DOM, and the declaration group specifies the style to apply. +Beautiful! You have now an inspector on your fisrt (empty and useless) style +sheet. Let's do something more useful now. Real stylesheets are composed of +rules (or rule-sets), where each has a selector and a declaration group. The +selector determines if the rule applies to some element in the DOM, and the +declaration group specifies the style to apply. ## Basics @@ -23,24 +28,39 @@ CascadingStyleSheetBuilder new with: [:style | style margin: 2 px ]; build ``` + Evaluates to: + ```css div { margin: 2px; } ``` -Let's analyze it. The message `declareRuleSetFor:with:` is used to configure a rule-set in the builder. It uses two closures, the first one is used to define the *selector* and the second one the *style*. The `selector` argument of the first closure provides an API to construct the selector (more on this later). The `style` argument on the second closure provides the API to declare CSS properties with their corresponding values. + +Let's analyze it. The message `declareRuleSetFor:with:` is used to configure a +rule-set in the builder. It uses two closures, the first one is used to define +the *selector* and the second one the *style*. The `selector` argument of the +first closure provides an API to construct the selector (more on this later). +The `style` argument on the second closure provides the API to declare CSS +properties with their corresponding values. The properties API is mostly defined following these rules: -- Properties without dashes in the name are directly mapped: to define `margin` we use the message `margin:`. -- Properties with one or more dashes are mapped using camel case: to define `margin-top` we use the message `marginTop:`. + +- Properties without dashes in the name are directly mapped: to define `margin` + we use the message `margin:`. +- Properties with one or more dashes are mapped using camel case: to define + `margin-top` we use the message `marginTop:`. ### Basic CSS Types #### Lengths, Angles, Times and Frequencies -Another thing to note is how `2 px` was interpreted. The resulting object is a `CssMeasure`. The library provides out-of-the-box support for the length, angle, time and frequency units in the CSS spec. There are extensions for `Integer` and `Float` classes allowing to obtain lengths. The supported length units are: +Another thing to note is how `2 px` was interpreted. The resulting object is a +`CssMeasure`. The library provides out-of-the-box support for the length, angle, +time and frequency units in the CSS spec. There are extensions for `Integer` and +`Float` classes allowing to obtain lengths. The supported length units are: + - `em` relative to font size - `ex` relative to "x" height - `ch` relative to width of the zero glyph in the element's font @@ -57,22 +77,28 @@ Another thing to note is how `2 px` was interpreted. The resulting object is a ` - `px` pixels (note that CSS has some special definition for pixel) The supported angle units are: + - `deg` degrees - `grad` gradians - `rad` radians - `turn` turns The supported time units are: + - `s` seconds - `ms` milliseconds The supported frequency units are: + - `Hz` Hertz - `kHz` KiloHertz -It also supports the creation of percentages: `50 percent` is expressed as `50%` in the resulting CSS. +It also supports the creation of percentages: `50 percent` is expressed as `50%` +in the resulting CSS. + +Some properties require integer or floating point values. In this cases just use +the Pharo provided integer and float support. For example: -Some properties require integer or floating point values. In this cases just use the Pharo provided integer and float support. For example: ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector div ] @@ -82,7 +108,11 @@ CascadingStyleSheetBuilder new #### Colors -The library also supports abstractions for properties requiring color values. You can reference the colors in the SVG 1.0 list by name, and the abstractions `CssRGBColor` and `CssHSLColor` allow the creation of colors in the RGB or HSL space including alpha support. To get the list of supported colors inspect `RenoirSt constants >> #colors`. +The library also supports abstractions for properties requiring color values. +You can reference the colors in the SVG 1.0 list by name, and the abstractions +`CssRGBColor` and `CssHSLColor` allow the creation of colors in the RGB or HSL +space including alpha support. To get the list of supported colors inspect +`RenoirSt constants >> #colors`. ```smalltalk CascadingStyleSheetBuilder new @@ -95,35 +125,44 @@ CascadingStyleSheetBuilder new ``` Evaluates to: + ```css div { - background-color: aliceblue; - border-color: rgba(0,128,0,0.5); + background-color: aliceblue; + border-color: rgba(0,128,0,0.5); } ``` -> **Hint:** In a real scenario you should never hardcode the colors as in the examples, instead put them in objects representing a theme or something that gives them a name related to your application. + +> **Hint:** In a real scenario you should never hardcode the colors as in the +> examples, instead put them in objects representing a theme or something that +> gives them a name related to your application. RGB-Colors also support percentual values: ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector div ] - with: [:style | style borderColor: (CssRGBColor red: 0 percent green: 50 percent blue: 0 percent) ]; + with: [:style | style borderColor: + (CssRGBColor red: 0 percent green: 50 percent blue: 0 percent) ]; build ``` + Evaluates to: + ```css div { - border-color: rgb(0%,50%,0%); + border-color: rgb(0%,50%,0%); } ``` + Notice the difference in the message used because there is no alpha channel specification. #### Constants -A lot of values for CSS properties are just keyword constants. You can reference it by keyword, inspect `RenoirSt constants` to get the list of supported ones. +A lot of values for CSS properties are just keyword constants. You can reference +it by keyword, inspect `RenoirSt constants` to get the list of supported ones. ```smalltalk CascadingStyleSheetBuilder new @@ -131,17 +170,21 @@ CascadingStyleSheetBuilder new with: [:style | style textAlign: #justify ]; build ``` + Evaluates to: + ```css div { - text-align: justify; + text-align: justify; } ``` #### Several Property Values -Some properties support a wide range of values. For example the `margin` property can have 1, 2 , 3 or 4 values specified. If only one value needs to be specified just provide it, in other case use an `Array` like this: +Some properties support a wide range of values. For example the `margin` +property can have 1, 2 , 3 or 4 values specified. If only one value needs to be +specified just provide it, in other case use an `Array` like this: ```smalltalk CascadingStyleSheetBuilder new @@ -149,35 +192,43 @@ CascadingStyleSheetBuilder new with: [:style | style margin: { 2 px. 4 px } ]; build ``` + Evaluates to: + ```css div { - margin: 2px 4px; + margin: 2px 4px; } ``` + #### URLs -`ZnUrl` instances can be used as the value for properties requiring an URI. Both relative and absolute URLs are accepted. A relative URL is by default considered relative to the site root. +`ZnUrl` instances can be used as the value for properties requiring an URI. +Both relative and absolute URLs are accepted. A relative URL is by default +considered relative to the site root. ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector div class: 'logo' ] with: [:style | style backgroundImage: 'images/logo.png' asZnUrl ]; declareRuleSetFor: [:selector | selector div class: 'logo' ] - with: [:style | style backgroundImage: 'http://www.example.com/images/logo.png' asZnUrl ]; + with: [:style | style + backgroundImage: 'http://www.example.com/images/logo.png' asZnUrl ]; build ``` + Evaluates to: + ```css div.logo { - background-image: url("/images/logo.png"); + background-image: url("/images/logo.png"); } div.logo { - background-image: url("http://www.example.com/images/logo.png"); + background-image: url("http://www.example.com/images/logo.png"); } ``` @@ -189,17 +240,20 @@ CascadingStyleSheetBuilder new with: [:style | style backgroundImage: 'images/logo.png' asZnUrl relativeToStyleSheet]; build ``` + Evaluates to: + ```css div.logo { - background-image: url("images/logo.png"); + background-image: url("images/logo.png"); } ``` ### Comments -When declaring rule sets the library support attaching comments to them. To do that send the message `declareRuleSetFor:with:andComment:`, for example: +When declaring rule sets the library support attaching comments to them. To do +that send the message `declareRuleSetFor:with:andComment:`, for example: ```smalltalk CascadingStyleSheetBuilder new @@ -208,96 +262,126 @@ CascadingStyleSheetBuilder new andComment: 'Two picas margin'; build ``` + Evaluates to: + ```css /*Two picas margin*/ div { - margin: 2pc; + margin: 2pc; } ``` -Since version 1.3.0 is possible to also define stand-alone comments (not attached to any rule): +Since version 1.3.0 is possible to also define stand-alone comments (not +attached to any rule): ```smalltalk CascadingStyleSheetBuilder new comment: 'A general comment'; build ``` + Evaluates to: + ```css /*A general comment*/ ``` ### Functional Notation -A functional notation is a type of CSS component value that can represent more complex types or invoke special processing. The following notations are supported: +A functional notation is a type of CSS component value that can represent more +complex types or invoke special processing. The following notations are supported: #### Mathematical Expressions: `calc()` -The library provides support for math expressions using the `CssMathExpression` abstraction. This math expressions are built instantiating a `CssMathExpression` with the first operand, and sending to it `+`, `-`, `*` or `/` messages. Lets see some example: +The library provides support for math expressions using the `CssMathExpression` +abstraction. This math expressions are built instantiating a `CssMathExpression` +with the first operand, and sending to it `+`, `-`, `*` or `/` messages. Lets +see some example: + ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector div ] with: [:style | style margin: (CssMathExpression on: 2 pc) / 3 + 2 percent ]; build ``` + Evaluates to: + ```css div { - margin: calc(2pc / 3 + 2%); + margin: calc(2pc / 3 + 2%); } ``` #### Toggling between values: `toggle()` -This kind of expressions allows descendant elements to cycle over a list of values instead of inheriting the same value. It's supported using the `CssToggle` abstraction. +This kind of expressions allows descendant elements to cycle over a list of +values instead of inheriting the same value. +It's supported using the `CssToggle` abstraction. ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector unorderedList unorderedList ] - with: [:style | style listStyleType: (CssToggle cyclingOver: { #disc. #circle. #square}) ]; + with: [:style | style listStyleType: + (CssToggle cyclingOver: { #disc. #circle. #square}) ]; build ``` + Evaluates to: + ```css ul ul { - list-style-type: toggle(disc, circle, square); + list-style-type: toggle(disc, circle, square); } ``` #### Attribute references: `attr()` -The attr() function is allowed as a component value in properties applied to an element or pseudo-element. It returns the value of an attribute on the element. If used on a pseudo-element, it returns the value of the attribute on the pseudo-element's originating element. It's supported using the `CssAttributeReference` abstraction. This function can be used simply providing an attribute name: +The attr() function is allowed as a component value in properties applied to an +element or pseudo-element. It returns the value of an attribute on the element. +If used on a pseudo-element, it returns the value of the attribute on the +pseudo-element's originating element. It's supported using the +`CssAttributeReference` abstraction. This function can be used simply providing +an attribute name: ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector div before ] - with: [:style | style content: (CssAttributeReference toAttributeNamed: 'title') ]; + with: [:style | style content: + (CssAttributeReference toAttributeNamed: 'title') ]; build ``` + Evaluates to: + ```css div::before { - content: attr(title string); + content: attr(title string); } ``` -or providing also the type or unit of the attribute (if no type or unit is specified the `string` type is assumed): + +or providing also the type or unit of the attribute (if no type or unit is +specified the `string` type is assumed): ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector div ] - with: [:style | style width: (CssAttributeReference toAttributeNamed: 'height' ofType: #pixel) ]; + with: [:style | style width: + (CssAttributeReference toAttributeNamed: 'height' ofType: #pixel) ]; build ``` + Evaluates to: + ```css div { - width: attr(height px); + width: attr(height px); } ``` @@ -306,53 +390,74 @@ also it's possible to provide a fallback value in case the attribute is not pres ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector div before ] - with: [:style | style content: (CssAttributeReference toStringAttributeNamed: 'title' withFallback: 'Missing title') ]; + with: [:style | style content: + (CssAttributeReference toStringAttributeNamed: 'title' + withFallback: 'Missing title') ]; build ``` + Evaluates to: + ```css div::before { - content: attr(title string, "Missing title"); + content: attr(title string, "Missing title"); } ``` ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector div before ] - with: [:style | style content: (CssAttributeReference toAttributeNamed: 'height' ofType: #pixel withFallback: 10 px) ]; + with: [:style | style content: + (CssAttributeReference toAttributeNamed: 'height' + ofType: #pixel withFallback: 10 px) ]; build ``` + Evaluates to: + ```css div::before { - content: attr(height px, 10px); + content: attr(height px, 10px); } ``` To get a list of the supported units inspect `RenoirSt constants >> #units`. -#### Gradients: `linear-gradient()` `radial-gradient()` `repeating-linear-gradient()` `repeating-radial-gradient()` +#### Gradients -A gradient is an image that smoothly fades from one color to another. These are commonly used for subtle shading in background images, buttons, and many other things. The gradient notations described in this section allow an author to specify such an image in a terse syntax, so that the UA can generate the image automatically when rendering the page. This notation is supported using `CssLinearGradient` and `CssRadialGradient` asbtractions. +A gradient is an image that smoothly fades from one color to another. These are +commonly used for subtle shading in background images, buttons, and many other +things. The gradient notations described in this section allow an author to +specify such an image in a terse syntax, so that the UA can generate the image +automatically when rendering the page. This notation is supported using +`CssLinearGradient` and `CssRadialGradient` asbtractions. Let's see some examples for linear gradients: ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector div ] - with: [:style | style background: (CssLinearGradient fading: { #yellow. #blue }) ]; + with: [:style | style background: + (CssLinearGradient fading: { #yellow. #blue }) ]; declareRuleSetFor: [:selector | selector div ] - with: [:style | style background: (CssLinearGradient to: #bottom fading: { #yellow. #blue }) ]; + with: [:style | style background: + (CssLinearGradient to: #bottom fading: { #yellow. #blue }) ]; declareRuleSetFor: [:selector | selector div ] - with: [:style | style background: (CssLinearGradient rotated: 45 deg fading: { #yellow. #blue }) ]; + with: [:style | style background: + (CssLinearGradient rotated: 45 deg fading: { #yellow. #blue }) ]; declareRuleSetFor: [:selector | selector div ] - with: [:style | style background: (CssLinearGradient rotated: 90 deg fading: { #yellow. (CssColorStop for: #blue at: 30 percent) }) ]; + with: [:style | style background: + (CssLinearGradient rotated: 90 deg + fading: { #yellow. (CssColorStop for: #blue at: 30 percent) }) ]; declareRuleSetFor: [:selector | selector div ] - with: [:style | style background: (CssLinearGradient fading: { #yellow. (CssColorStop for: #blue at: 20 percent). #green}) ]; + with: [:style | style background: + (CssLinearGradient fading: + { #yellow. (CssColorStop for: #blue at: 20 percent). #green}) ]; declareRuleSetFor: [:selector | selector div ] - with: [:style | style background: (CssLinearGradient to: { #top. #right } fading: { #red. #white. #blue }) ]; + with: [:style | style background: + (CssLinearGradient to: { #top. #right } fading: { #red. #white. #blue }) ]; build ``` @@ -361,86 +466,112 @@ evaluates to: ```css div { - background: linear-gradient(yellow, blue); + background: linear-gradient(yellow, blue); } div { - background: linear-gradient(to bottom, yellow, blue); + background: linear-gradient(to bottom, yellow, blue); } div { - background: linear-gradient(45deg, yellow, blue); + background: linear-gradient(45deg, yellow, blue); } div { - background: linear-gradient(90deg, yellow, blue 30%); + background: linear-gradient(90deg, yellow, blue 30%); } div { - background: linear-gradient(yellow, blue 20%, green); + background: linear-gradient(yellow, blue 20%, green); } div { - background: linear-gradient(to top right, red, white, blue); + background: linear-gradient(to top right, red, white, blue); } ``` and some for radial gradients: + ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector div ] - with: [:style | style background: (CssRadialGradient fading: { #yellow. #green }) ]; + with: [:style | style background: + (CssRadialGradient fading: { #yellow. #green }) ]; declareRuleSetFor: [:selector | selector div ] - with: [:style | style background: (CssRadialGradient elliptical: #farthestCorner at: #center fading: { #yellow. #green }) ]; + with: [:style | style background: + (CssRadialGradient + elliptical: #farthestCorner + at: #center + fading: { #yellow. #green }) ]; declareRuleSetFor: [:selector | selector div ] - with: [:style | style background: (CssRadialGradient elliptical: #farthestSide at: { #left. #bottom} fading: { #red. (CssColorStop for: #yellow at: 50 px). #green }) ]; + with: [:style | style background: + (CssRadialGradient + elliptical: #farthestSide + at: { #left. #bottom} + fading: { #red. (CssColorStop for: #yellow at: 50 px). #green }) ]; declareRuleSetFor: [:selector | selector div ] - with: [:style | style background: (CssRadialGradient elliptical: {20 px. 30 px} at: { 20 px. 30 px} fading: { #red. #yellow. #green }) ]; + with: [:style | style background: + (CssRadialGradient + elliptical: {20 px. 30 px} + at: { 20 px. 30 px} + fading: { #red. #yellow. #green }) ]; build ``` + evaluates to: + ```css div { - background: radial-gradient(yellow, green); + background: radial-gradient(yellow, green); } div { - background: radial-gradient(farthest-corner ellipse at center, yellow, green); + background: radial-gradient(farthest-corner ellipse at center, yellow, green); } div { - background: radial-gradient(farthest-side ellipse at left bottom, red, yellow 50px, green); + background: radial-gradient(farthest-side ellipse at left bottom, red, yellow 50px, green); } div { - background: radial-gradient(20px 30px ellipse at 20px 30px, red, yellow, green); + background: radial-gradient(20px 30px ellipse at 20px 30px, red, yellow, green); } ``` To make the gradient repeatable, just send to it the message `beRepeating`. For Example: + ```smalltalk (CssRadialGradient fading: { #yellow. #green }) beRepeating ``` + renders as: + ```css repeating-radial-gradient(yellow, green); ``` + #### Transforms -Css transforms are a collection of functions that allow you to shape elements in particular ways. + +Css transforms are a collection of functions that allow you to shape elements +in particular ways. + ##### Rotation: `rotate()` `rotateX()` `rotateY()` `rotateZ()` `rotate3d()` -The library provides support for rotation functions, used in animations to move an element around a central point. The rotate expressions are built instantiating `CssRotate` or `CssRotate3D` for 3D rotations. +The library provides support for rotation functions, used in animations to move +an element around a central point. The rotate expressions are built +instantiating `CssRotate` or `CssRotate3D` for 3D rotations. Lets see a basic working rotation example: + ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [ :selector | selector div ] @@ -464,42 +595,46 @@ CascadingStyleSheetBuilder new forKeyframesNamed: 'spin'; build ``` + Evaluates to: + ```css div { - animation: spin 5s linear infinite; - width: 100px; - height: 100px; + animation: spin 5s linear infinite; + width: 100px; + height: 100px; } @keyframes spin { - 0% - { - transform: rotate(0deg); - background: blue; - } - - 100% - { - transform: rotate(360deg); - background: red; - } + 0% + { + transform: rotate(0deg); + background: blue; + } + + 100% + { + transform: rotate(360deg); + background: red; + } } ``` ##### Translation: `translate()` `translateX()` `translateY()` `translateZ()` `translate3d()` -The library supports `translate` functions, used to mode the position of an element. To translate an element, instantiate `CssTranslate`. +The library supports `translate` functions, used to mode the position of an +element. To translate an element, instantiate `CssTranslate`. Lets see an example: + ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [ :selector | selector div ] with: [ :style | style - background: #blue; + background: #blue; animation: 'animation 5s linear infinite'; width: 100 px; height: 100 px ]; @@ -510,129 +645,143 @@ CascadingStyleSheetBuilder new style transform: (CssTranslate by: 100 px) ] ] forKeyframesNamed: 'animation'; - build. + build. ``` + Evaluates to: + ```css div { - background: blue; - animation: animation 5s linear infinite; - width: 100px; - height: 100px; + background: blue; + animation: animation 5s linear infinite; + width: 100px; + height: 100px; } @keyframes animation { - 0% - { - transform: translate(100px); - } + 0% + { + transform: translate(100px); + } } ``` ##### Scale: `scale()` `scaleX()` `scaleY()` `scaleZ()` `scale3d()` -RenoirSt supports scaling functions. You can use them by building an instance of `CssScale`. +RenoirSt supports scaling functions. You can use them by building an instance +of `CssScale`. An example can be: + ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [ :selector | selector div ] with: [ :style | style - background: #blue; - animation: 'scale 5s linear infinite'; - width: 100 px; - height: 100 px ]; + background: #blue; + animation: 'scale 5s linear infinite'; + width: 100 px; + height: 100 px ]; declare: [ :cssBuilder | cssBuilder declareKeyframeRuleSetAt: 0 percent with: [ :style | - style transform: (CssScale by: 2) ]; - declareKeyframeRuleSetAt: 100 percent - with: [ :style | - style transform: (CssScale by: 4) ] ] + style transform: (CssScale by: 2) ]; + declareKeyframeRuleSetAt: 100 percent + with: [ :style | + style transform: (CssScale by: 4) ] ] forKeyframesNamed: 'scale'; - build. + build. ``` + Evaluating to: + ```css div { - background: blue; - animation: scale 5s linear infinite; - width: 100px; - height: 100px; + background: blue; + animation: scale 5s linear infinite; + width: 100px; + height: 100px; } @keyframes scale { - 0% - { - transform: scale(2); - } - - 100% - { - transform: scale(4); - } + 0% + { + transform: scale(2); + } + + 100% + { + transform: scale(4); + } } ``` ##### Skew `skew()` `skewX()` `skewY()` -The library supports the `skew` function, performing a shear transformation (also known as a shear mapping or a transvection), which displaces each point of an element by a given angle in each direction. To build skew functions, instantiate `CssSkew`. +The library supports the `skew` function, performing a shear transformation +(also known as a shear mapping or a transvection), which displaces each point +of an element by a given angle in each direction. To build skew functions, +instantiate `CssSkew`. An example: + ```smalltalk CascadingStyleSheetBuilder new - declareRuleSetFor: [ :selector | selector div ] - with: [ :style | - style - background: #blue; - animation: 'skewAnimation 5s linear infinite'; - width: 100 px; - height: 100 px ]; - declare: [ :cssBuilder | - cssBuilder - declareKeyframeRuleSetAt: 0 percent - with: [ :style | style transform: (CssSkew by: 45 deg) ] ] - forKeyframesNamed: 'skewAnimation'; - build + declareRuleSetFor: [ :selector | selector div ] + with: [ :style | + style + background: #blue; + animation: 'skewAnimation 5s linear infinite'; + width: 100 px; + height: 100 px ]; + declare: [ :cssBuilder | + cssBuilder + declareKeyframeRuleSetAt: 0 percent + with: [ :style | style transform: (CssSkew by: 45 deg) ] ] + forKeyframesNamed: 'skewAnimation'; + build ``` + Evaluates to: + ```css div { - background: blue; - animation: skewAnimation 5s linear infinite; - width: 100px; - height: 100px; + background: blue; + animation: skewAnimation 5s linear infinite; + width: 100px; + height: 100px; } @keyframes skewAnimation { - 0% - { - transform: skew(45deg); - } + 0% + { + transform: skew(45deg); + } } ``` ##### Aditional Functions for Transformation + ###### Perspective The library supports the `perspective` function by instantiating `CssPerspective`. This function is used to set a perspective when doing a transformation on the Z axis. If we extend the previous example to translate in a 3D space, it would be like: + ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [ :selector | selector div ] with: [ :style | style - background: #blue; + background: #blue; animation: 'animation 5s linear infinite'; width: 100 px; height: 100 px ]; @@ -642,30 +791,32 @@ CascadingStyleSheetBuilder new with: [ :style | style transform: - {(CssPerspective of: 200 px) . + {(CssPerspective of: 200 px) . (CssTranslate onXAxisBy: 100 px onYAxisBy: 100 px andZAxisBy: 100 px )} ] ] forKeyframesNamed: 'animation'; - build. + build. ``` + Evaluating to: + ```css div { - background: blue; - animation: animation 5s linear infinite; - width: 100px; - height: 100px; + background: blue; + animation: animation 5s linear infinite; + width: 100px; + height: 100px; } @keyframes animation { - 0% - { - transform: perspective(200px) translate3d(100px, 100px, 100px); - } + 0% + { + transform: perspective(200px) translate3d(100px, 100px, 100px); + } } ``` @@ -673,136 +824,168 @@ div ##### Steps -The library also supports the `steps` function, used in the timing parameter of animation keyframes called `animation-timing-function`. Steps are a timing function that allows us to break an animation or transition into segments. +The library also supports the `steps` function, used in the timing parameter of +animation keyframes called `animation-timing-function`. Steps are a timing +function that allows us to break an animation or transition into segments. A usage example can be: + ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [ :selector | selector div ] with: [ :style | style - background: #blue; - animationName: 'scale'; - animationDuration: 5 s; - animationTimingFunction: (CssSteps by: 2); - animationIterationCount: #infinite; - width: 100 px; - height: 100 px ]; + background: #blue; + animationName: 'scale'; + animationDuration: 5 s; + animationTimingFunction: (CssSteps by: 2); + animationIterationCount: #infinite; + width: 100 px; + height: 100 px ]; declare: [ :cssBuilder | cssBuilder declareKeyframeRuleSetAt: 0 percent with: [ :style | - style transform: (CssScale by: 2) ]; - declareKeyframeRuleSetAt: 100 percent - with: [ :style | - style transform: (CssScale by: 4) ] ] + style transform: (CssScale by: 2) ]; + declareKeyframeRuleSetAt: 100 percent + with: [ :style | + style transform: (CssScale by: 4) ] ] forKeyframesNamed: 'scale'; - build. + build. ``` + Evaluating to: + ```css div { - background: blue; - animation-name: scale; - animation-duration: 5s; - animation-timing-function: steps(2); - animation-iteration-count: infinite; - width: 100px; - height: 100px; + background: blue; + animation-name: scale; + animation-duration: 5s; + animation-timing-function: steps(2); + animation-iteration-count: infinite; + width: 100px; + height: 100px; } @keyframes scale { - 0% - { - transform: scale(2); - } - - 100% - { - transform: scale(4); - } + 0% + { + transform: scale(2); + } + + 100% + { + transform: scale(4); + } } ``` ##### Cubic Bezier -Renoir supports the `cubic-bezier` function, that can be used with the `transition-timing-function` property to control how a transition will change speed over its duration. It also works with the `animation-timing-function` for keyframes. To create your own cubic bezier timing function build an instance with `CssCubicBezier`. +Renoir supports the `cubic-bezier` function, that can be used with the +`transition-timing-function` property to control how a transition will change +speed over its duration. It also works with the `animation-timing-function` for +keyframes. To create your own cubic bezier timing function build an instance +with `CssCubicBezier`. Here's an example: + ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [ :selector | selector div ] with: [ :style | style - background: #blue; - animationName: 'scale'; - animationDuration: 5 s; - animationTimingFunction: ( - CssCubicBezier - firstXAxis: 0.63 - firstYAxis: 0.05 - secondXAxis: 0.43 - secondYAxis: 1.7); - animationIterationCount: #infinite; - width: 100 px; - height: 100 px ]; + background: #blue; + animationName: 'scale'; + animationDuration: 5 s; + animationTimingFunction: ( + CssCubicBezier + firstXAxis: 0.63 + firstYAxis: 0.05 + secondXAxis: 0.43 + secondYAxis: 1.7); + animationIterationCount: #infinite; + width: 100 px; + height: 100 px ]; declare: [ :cssBuilder | cssBuilder - declareKeyframeRuleSetAt: 0 percent - with: [ :style | - style transform: (CssScale by: 2) ]; - declareKeyframeRuleSetAt: 100 percent - with: [ :style | - style transform: (CssScale by: 4) ] ] + declareKeyframeRuleSetAt: 0 percent + with: [ :style | + style transform: (CssScale by: 2) ]; + declareKeyframeRuleSetAt: 100 percent + with: [ :style | + style transform: (CssScale by: 4) ] ] forKeyframesNamed: 'scale'; - build. + build. ``` + Evaluating to: + ```css div { - background: blue; - animation-name: scale; - animation-duration: 5s; - animation-timing-function: cubic-bezier(0.63, 0.05, 0.43, 1.7); - animation-iteration-count: infinite; - width: 100px; - height: 100px; + background: blue; + animation-name: scale; + animation-duration: 5s; + animation-timing-function: cubic-bezier(0.63, 0.05, 0.43, 1.7); + animation-iteration-count: infinite; + width: 100px; + height: 100px; } @keyframes scale { - 0% - { - transform: scale(2); - } - - 100% - { - transform: scale(4); - } + 0% + { + transform: scale(2); + } + + 100% + { + transform: scale(4); + } } ``` #### Box Shadows -This abstraction simplifies the use of the `box-shadow` property. Let's see some examples: +This abstraction simplifies the use of the `box-shadow` property. Let's see +some examples: ```smalltalk -CssBoxShadow horizontalOffset: 64 px verticalOffset: 64 px blurRadius: 12 px spreadDistance: 40 px color: #black +CssBoxShadow + horizontalOffset: 64 px + verticalOffset: 64 px + blurRadius: 12 px + spreadDistance: 40 px + color: #black ``` + renders as: + ```css 64px 64px 12px 40px black ``` ```smalltalk -(CssBoxShadow horizontalOffset: 64 px verticalOffset: 64 px blurRadius: 12 px spreadDistance: 40 px color: #black) , -(CssBoxShadow horizontalOffset: 12 px verticalOffset: 11 px blurRadius: 0 px spreadDistance: 8 px color: #black ) beInset +(CssBoxShadow + horizontalOffset: 64 px + verticalOffset: 64 px + blurRadius: 12 px + spreadDistance: 40 px + color: #black) , +(CssBoxShadow + horizontalOffset: 12 px + verticalOffset: 11 px + blurRadius: 0 px + spreadDistance: 8 px + color: #black ) beInset ``` + renders as: + ```css 64px 64px 12px 40px black, inset 12px 11px 0px 8px black ``` diff --git a/docs/tutorial/Tutorial-Part-II.md b/docs/tutorial/Tutorial-Part-II.md index 0507a6a..c03c791 100644 --- a/docs/tutorial/Tutorial-Part-II.md +++ b/docs/tutorial/Tutorial-Part-II.md @@ -1,13 +1,18 @@ -Tutorial - Part II -================== +# Tutorial - Part II ## Selectors -So far our focus was on the *style* part of the rule. Let's focus now on the available *selectors*. Remember that a CSS selector represents a structure used to match elements in the document tree. This chapter asume some familiarity with the CSS selectors and will not go in detail about the exact meaning of each one. For more details you can take a look at http://www.w3.org/TR/css3-selectors/. +So far our focus was on the *style* part of the rule. Let's focus now on the +available *selectors*. Remember that a CSS selector represents a structure used +to match elements in the document tree. This chapter asume some familiarity with +the CSS selectors and will not go in detail about the exact meaning of each one. +For more details you can take a look at . ### Type selectors -These selectors match a specific element type in the DOM. The library provides out-of-the-box support for HTML elements. One example is the `div` selector used in the previous chapter. Another is the following: +These selectors match a specific element type in the DOM. The library provides +out-of-the-box support for HTML elements. One example is the `div` selector used +in the previous chapter. Another is the following: ```smalltalk CascadingStyleSheetBuilder new @@ -15,131 +20,155 @@ CascadingStyleSheetBuilder new with: [:style | style listStyleType: #lowerRoman ]; build ``` + ```css ol { - list-style-type: lower-roman; + list-style-type: lower-roman; } ``` -To get a list of the supported type selectors inspect `CssSelector selectorsInProtocol: '*RenoirSt-HTML'`. +To get a list of the supported type selectors inspect +`CssSelector selectorsInProtocol: '*RenoirSt-HTML'`. ### Combinators One of the most common use cases is the **descendant combinator**. + ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector div orderedList ] with: [:style | style listStyleType: #lowerRoman ]; build ``` + ```css div ol { - list-style-type: lower-roman; + list-style-type: lower-roman; } ``` In case you need to use parenthesis in the right part of the expression, use `/`. + ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector div / (selector class: 'custom') ] with: [:style | style listStyleType: #lowerRoman ]; build ``` + ```css div .custom { - list-style-type: lower-roman; + list-style-type: lower-roman; } ``` #### Child combinator + ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector div > selector orderedList ] with: [:style | style listStyleType: #lowerRoman ]; build ``` + ```css div > ol { - list-style-type: lower-roman; + list-style-type: lower-roman; } ``` #### Adjacent & General Siblings combinators + ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector div + selector orderedList ] with: [:style | style listStyleType: #lowerRoman ]; build ``` + ```css div + ol { - list-style-type: lower-roman; + list-style-type: lower-roman; } ``` + ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector div ~ selector orderedList ] with: [:style | style listStyleType: #lowerRoman ]; build ``` + ```css div ~ ol { - list-style-type: lower-roman; + list-style-type: lower-roman; } ``` ### Class and Id Selectors + ```smalltalk CascadingStyleSheetBuilder new - declareRuleSetFor: [:selector | (selector div class: 'pastoral') id: #account5 ] + declareRuleSetFor: [:selector | + (selector div class: 'pastoral') id: #account5 ] with: [:style | style listStyleType: #lowerRoman ]; build ``` + ```css div.pastoral#account5 { - list-style-type: lower-roman; + list-style-type: lower-roman; } ``` -> **Hint:** You should not hardcode the classes and ids, they should be obtained from the same object that holds them for the HTML generation. You probably have some code setting the class(es) and/or id(s) to a particular HTML element. + +> **Hint:** You should not hardcode the classes and ids, they should be obtained +> from the same object that holds them for the HTML generation. You probably +> have some code setting the class(es) and/or id(s) to a particular HTML element. ### Attribute Selectors -Attribute selectors are useful to match an element if that element has an attribute that matches the attribute represented by the selectors. +Attribute selectors are useful to match an element if that element has an +attribute that matches the attribute represented by the selectors. #### Attribute presence and value selectors Attribute presence: + ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector h1 havingAttribute: 'title' ] with: [:style | style color: #blue ]; build ``` + ```css h1[title] { - color: blue; + color: blue; } ``` exact attribute value matching: + ```smalltalk CascadingStyleSheetBuilder new - declareRuleSetFor: [:selector | selector span withAttribute: 'class' equalTo: 'example' ] + declareRuleSetFor: [:selector | + selector span withAttribute: 'class' equalTo: 'example' ] with: [:style | style color: #blue ]; build ``` + ```css span[class="example"] { - color: blue; + color: blue; } ``` @@ -147,81 +176,99 @@ inclusion: ```smalltalk CascadingStyleSheetBuilder new - declareRuleSetFor: [:selector | selector anchor attribute: 'rel' includes: 'copyright' ] + declareRuleSetFor: [:selector | + selector anchor attribute: 'rel' includes: 'copyright' ] with: [:style | style color: #blue ]; build ``` + ```css a[rel~="copyright"] { - color: blue; + color: blue; } ``` + and: ```smalltalk CascadingStyleSheetBuilder new - declareRuleSetFor: [:selector | selector anchor firstValueOfAttribute: 'hreflang' beginsWith: 'en' ] + declareRuleSetFor: [:selector | + selector anchor firstValueOfAttribute: 'hreflang' beginsWith: 'en' ] with: [:style | style color: #blue ]; build ``` + ```css a[hreflang|="en"] { - color: blue; + color: blue; } ``` #### Substring matching attribute selectors This selectors are provided for matching substrings in the value of an attribute: + - `attribute:beginsWith:` - `attribute:endsWith:` - `attribute:includesSubstring:` ```smalltalk CascadingStyleSheetBuilder new - declareRuleSetFor: [:selector | selector anchor attribute: 'type' beginsWith: 'image/' ] + declareRuleSetFor: [:selector | + selector anchor attribute: 'type' beginsWith: 'image/' ] with: [:style | style color: #blue ]; build ``` + ```css a[type^="image/"] { - color: blue; + color: blue; } ``` ```smalltalk CascadingStyleSheetBuilder new - declareRuleSetFor: [:selector | selector anchor attribute: 'type' endsWith: '.html' ] + declareRuleSetFor: [:selector | + selector anchor attribute: 'type' endsWith: '.html' ] with: [:style | style color: #blue ]; build ``` + ```css a[type$=".html"] { - color: blue; + color: blue; } ``` ```smalltalk CascadingStyleSheetBuilder new - declareRuleSetFor: [:selector | selector paragraph attribute: 'title' includesSubstring: 'hello' ] + declareRuleSetFor: [:selector | + selector paragraph attribute: 'title' includesSubstring: 'hello' ] with: [:style | style color: #blue ]; build ``` + ```css p[title*="hello"] { - color: blue; + color: blue; } ``` ### Pseudo-Classes -The pseudo-class concept is introduced to allow selection based on information that lies outside of the document tree or that cannot be expressed using the simpler selectors. Most pseudo-classes are supported just by sending one of the following messages `link`, `visited`, `active`, `hover`, `focus`, `target`, `enabled`, `disabled` or `checked`. + +The pseudo-class concept is introduced to allow selection based on information +that lies outside of the document tree or that cannot be expressed using the +simpler selectors. Most pseudo-classes are supported just by sending one of the +following messages `link`, `visited`, `active`, `hover`, `focus`, `target`, +`enabled`, `disabled` or `checked`. Here is a small example that uses the pseudo-classes: + ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector anchor link ] @@ -236,71 +283,89 @@ CascadingStyleSheetBuilder new with: [:style | style color: #green ]; build ``` + ```css a:link { - color: blue; + color: blue; } a:visited:active { - color: green; + color: green; } a:focus:hover:enabled { - color: green; + color: green; } p.note:target:disabled { - color: green; + color: green; } input:checked { - color: green; + color: green; } ``` -#### Language Pseudo-class: +#### Language Pseudo-class + ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | (selector lang: 'es') > selector div ] with: [:style | style quotes: { '"«"'. '"»"' } ]; build ``` + ```css :lang(es) > div { - quotes: "«" "»"; + quotes: "«" "»"; } ``` -#### Negation Pseudo-class: +#### Negation Pseudo-class -The negation pseudo-class, `:not(X)`, is a functional notation taking a simple selector (excluding the negation pseudo-class itself) as an argument. It represents an element that is not represented by its argument. For more information take a look at: http://www.w3.org/TR/css3-selectors/#negation. +The negation pseudo-class, `:not(X)`, is a functional notation taking a simple +selector (excluding the negation pseudo-class itself) as an argument. It +represents an element that is not represented by its argument. +For more information take a look at: . This selector is supported sending the message `not:`. Lets see an example: + ```smalltalk CascadingStyleSheetBuilder new - declareRuleSetFor: [:selector | selector button not: (selector havingAttribute: 'DISABLED') ] + declareRuleSetFor: [:selector | + selector button not: (selector havingAttribute: 'DISABLED') ] with: [:style | style color: #blue ]; build ``` + ```css button:not([DISABLED]) { - color: blue; + color: blue; } ``` + #### Structural Pseudo-classes -These selectors allow selection based on extra information that lies in the document tree but cannot be represented by other simpler selectors nor combinators. -Standalone text and other non-element nodes are not counted when calculating the position of an element in the list of children of its parent. When calculating the position of an element in the list of children of its parent, the index numbering starts at 1. +These selectors allow selection based on extra information that lies in the +document tree but cannot be represented by other simpler selectors nor combinators. + +Standalone text and other non-element nodes are not counted when calculating +the position of an element in the list of children of its parent. When +calculating the position of an element in the list of children of its parent, +the index numbering starts at 1. ##### Root Pseudo-class -The :root pseudo-class represents an element that is the root of the document. To build this kind of selector just send the message `root` to another selector: + +The :root pseudo-class represents an element that is the root of the document. +To build this kind of selector just send the message `root` to another selector: + ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector root ] @@ -310,11 +375,19 @@ CascadingStyleSheetBuilder new ##### Kind of nth-child Pseudo-classes -The `:nth-child(an+b)` pseudo-class notation represents an element that has `an+b-1` siblings before it in the document tree, for any positive integer or zero value of n, and has a parent element. For values of a and b greater than zero, this effectively divides the element's children into groups of a elements (the last group taking the remainder), and selecting the bth element of each group. The a and b values must be integers (positive, negative, or zero). The index of the first child of an element is 1. +The `:nth-child(an+b)` pseudo-class notation represents an element that has +`an+b-1` siblings before it in the document tree, for any positive integer or +zero value of n, and has a parent element. For values of a and b greater than +zero, this effectively divides the element's children into groups of a elements +(the last group taking the remainder), and selecting the bth element of each +group. The a and b values must be integers (positive, negative, or zero). The +index of the first child of an element is 1. -In addition to this, `:nth-child()` can take ‘odd’ and ‘even’ as arguments instead. The value ‘odd’ is equivalent to 2n+1, whereas ‘even’ is equivalent to 2n. +In addition to this, `:nth-child()` can take ‘odd’ and ‘even’ as arguments +instead. The value ‘odd’ is equivalent to 2n+1, whereas ‘even’ is equivalent to 2n. -Since version 1.1.0 the library supports an abstraction for this kind of formulae (`CssLinealPolynomial`), or just an integer if `n` is not required. +Since version 1.1.0 the library supports an abstraction for this kind of +formulae (`CssLinealPolynomial`), or just an integer if `n` is not required. ```smalltalk CascadingStyleSheetBuilder new @@ -326,26 +399,30 @@ CascadingStyleSheetBuilder new with: [:style | style color: #blue ]; build ``` + ```css :nth-child(3n+1) { - color: blue; + color: blue; } :nth-child(5) { - color: blue; + color: blue; } :nth-child(even) { - color: blue; + color: blue; } ``` -`CssLinealPolynomial` instances can be created by sending the message `n` to an integer, and later this instances can receive the messages `+` or `-` to configure the independent coefficient. +`CssLinealPolynomial` instances can be created by sending the message `n` to an +integer, and later this instances can receive the messages `+` or `-` to +configure the independent coefficient. Some examples: + ```smalltalk 1 n "Prints as: n". 2 n -3 "Prints as: 2n-3". @@ -353,6 +430,7 @@ Some examples: ``` The rest of the selectors in this category are modeled using the following messsages: + - `nth-last-child()` -> `childFromLastAt:` - `nth-of-type()` -> `siblingOfTypeAt:` - `nth-last-of-type()` -> `siblingOfTypeFromLastAt:` @@ -366,9 +444,15 @@ The rest of the selectors in this category are modeled using the following messs ### Pseudo-Elements -Pseudo-elements create abstractions about the document tree beyond those specified by the document language. For instance, document languages do not offer mechanisms to access the first letter or first line of an element's content. Pseudo-elements allow authors to refer to this otherwise inaccessible information. Pseudo-elements may also provide authors a way to refer to content that does not exist in the source document. +Pseudo-elements create abstractions about the document tree beyond those +specified by the document language. For instance, document languages do not +offer mechanisms to access the first letter or first line of an element's +content. Pseudo-elements allow authors to refer to this otherwise inaccessible +information. Pseudo-elements may also provide authors a way to refer to content +that does not exist in the source document. #### First line + This selector describes the contents of the first formatted line of an element. ```smalltalk @@ -377,16 +461,18 @@ CascadingStyleSheetBuilder new with: [:style | style textTransform: #uppercase ]; build ``` + ```css p::first-line { - text-transform: uppercase; + text-transform: uppercase; } ``` #### First letter -This pseudo-element represents the first letter of an element, if it is not preceded by any other content (such as images or inline tables) on its line. +This pseudo-element represents the first letter of an element, if it is not +preceded by any other content (such as images or inline tables) on its line. ```smalltalk CascadingStyleSheetBuilder new @@ -394,16 +480,19 @@ CascadingStyleSheetBuilder new with: [:style | style fontSize: 200 percent ]; build ``` + ```css p::first-letter { - font-size: 200%; + font-size: 200%; } ``` #### Before and After -These pseudo-elements can be used to describe generated content before or after an element's content. The `content` property, in conjunction with these pseudo-elements, specifies what is inserted. +These pseudo-elements can be used to describe generated content before or after +an element's content. The `content` property, in conjunction with these +pseudo-elements, specifies what is inserted. ```smalltalk CascadingStyleSheetBuilder new @@ -413,25 +502,31 @@ CascadingStyleSheetBuilder new with: [:style | style content: '"[*]"' ]; build ``` + ```css p.note::before { - content: "Note: "; + content: "Note: "; } p.note::after { - content: "[*]"; + content: "[*]"; } ``` ### Selector Groups -A comma-separated list of selectors represents the union of all elements selected by each of the individual selectors in the list. For example, in CSS when several selectors share the same declarations, they may be grouped into a comma-separated list. +A comma-separated list of selectors represents the union of all elements +selected by each of the individual selectors in the list. For example, in CSS +when several selectors share the same declarations, they may be grouped into a +comma-separated list. ```smalltalk CascadingStyleSheetBuilder new - declareRuleSetFor: [:selector | (selector div class: 'note') after , (selector paragraph class: 'note') before ] + declareRuleSetFor: [:selector | + (selector div class: 'note') after , + (selector paragraph class: 'note') before ] with: [:style | style content: '"Note: "' ]; build ``` @@ -440,7 +535,7 @@ CascadingStyleSheetBuilder new div.note::after , p.note::before { - content: "Note: "; + content: "Note: "; } ``` diff --git a/docs/tutorial/Tutorial-Part-III.md b/docs/tutorial/Tutorial-Part-III.md index 14eec36..0a68d0f 100644 --- a/docs/tutorial/Tutorial-Part-III.md +++ b/docs/tutorial/Tutorial-Part-III.md @@ -1,13 +1,18 @@ -Tutorial - Part III -=================== +# Tutorial - Part III ## Important Rules -CSS attempts to create a balance of power between author and user style sheets. By default, rules in an author's style sheet override those in a user's style sheet. +CSS attempts to create a balance of power between author and user style sheets. +By default, rules in an author's style sheet override those in a user's style sheet. -However, for balance, an `!important` declaration takes precedence over a normal declaration. Both author and user style sheets may contain `!important` declarations, and user `!important` rules override author `!important` rules. This CSS feature improves accessibility of documents by giving users with special requirements control over presentation. +However, for balance, an `!important` declaration takes precedence over a normal +declaration. Both author and user style sheets may contain `!important` +declarations, and user `!important` rules override author `!important` rules. +This CSS feature improves accessibility of documents by giving users with +special requirements control over presentation. -The library provides support for this feature by sending `beImportantDuring:` message to the style. Let's see an example: +The library provides support for this feature by sending `beImportantDuring:` +message to the style. Let's see an example: ```smalltalk CascadingStyleSheetBuilder new @@ -22,44 +27,64 @@ CascadingStyleSheetBuilder new ]; build ``` + Evaluates to: + ```css p { - text-indent: 1em !important; - font-style: italic !important; - font-size: 18pt; + text-indent: 1em !important; + font-style: italic !important; + font-size: 18pt; } ``` -Note that the important properties must be created by sending the messages to the inner argument `importantStyle` instead of the outer argument `style`. -##### References: -- http://www.w3.org/TR/CSS2/cascade.html#important-rules +Note that the important properties must be created by sending the messages to +the inner argument `importantStyle` instead of the outer argument `style`. + +### References + +- ## Keyframes The `@keyframes` rule specifies the animation code. The animation is created by gradually changing from one set of CSS styles to another. During the animation, you can change the set of CSS styles many times. -Specify when the style change will happen in percent, or with the keywords "from" and "to", which is the same as 0% and 100%. 0% is the beginning of the animation, 100% is when the animation is complete. +Specify when the style change will happen in percent, or with the keywords +"from" and "to", which is the same as 0% and 100%. 0% is the beginning of the +animation, 100% is when the animation is complete. -**Tip:** For best browser support, you should always define both the 0% and the 100% selectors. +> **Tip:** For best browser support, you should always define both the 0% and the +> 100% selectors. A basic keyframe rule consists of specifying just a keyframe with some style rule: + ```smalltalk CascadingStyleSheetBuilder new - declare: [ :cssBuilder | - cssBuilder - declareKeyframeRuleSetAt: 0 percent - with: [ :style | style backgroundColor: #red ]; - declareKeyframeRuleSetAt: 100 percent - with: [ :style | style backgroundColor: #blue ] ] + declare: [ :cssBuilder | + cssBuilder + declareKeyframeRuleSetAt: 0 percent + with: [ :style | style backgroundColor: #red ]; + declareKeyframeRuleSetAt: 100 percent + with: [ :style | style backgroundColor: #blue ] ] forKeyframesNamed: 'example'; - build + build +``` + +To use keyframes in the library just send the message +`declare:forKeyframesNamed:` to the builder. The first closure is evaluated +with an instance of a `CascadingStyleSheetBuilder`. The second parameter is to +give a name to your keyframe rule. + +The style can be built with either the `animation:` shorthand: + +```css +animation: name duration timing-function delay iteration-count direction; ``` -To use keyframes in the library just send the message `declare:forKeyframesNamed:` to the builder. The first closure is evaluated with an instance of a `CascadingStyleSheetBuilder`. The second parameter is to give a name to your keyframe rule. -The style can be built with either the `animation:` shorthand (`animation: name duration timing-function delay iteration-count direction fill-mode play-state`) or with separate animation styles, such as: +or with separate animation styles, such as: + - `animationName:` - `animationDuration:` - `animationTimingFunction:` @@ -119,157 +144,185 @@ CascadingStyleSheetBuilder new background: '#f00' ] ] forKeyframesNamed: 'spin' ``` + Evaluating to: ```css div { - animation: spin 5s linear infinite; - max-height: 80vh; - font-size: larger; - background: #f00; - width: 100px; - height: 100px; - position: relative; + animation: spin 5s linear infinite; + max-height: 80vh; + font-size: larger; + background: #f00; + width: 100px; + height: 100px; + position: relative; } @keyframes spin { - 0% - { - transform: rotate(0deg); - background: #f00; - } - - 25% - { - transform: rotate(90deg); - background: #f99; - } - - 50% - { - transform: rotate(180deg); - background: #b88; - } - - 75% - { - transform: rotate(270deg); - background: #a66; - } - - 100% - { - transform: rotate(360deg); - background: #f00; - } + 0% + { + transform: rotate(0deg); + background: #f00; + } + + 25% + { + transform: rotate(90deg); + background: #f99; + } + + 50% + { + transform: rotate(180deg); + background: #b88; + } + + 75% + { + transform: rotate(270deg); + background: #a66; + } + + 100% + { + transform: rotate(360deg); + background: #f00; + } } ``` -**Note:** The `!important` rule is ignored in a keyframe +> **Note:** The `!important` rule is ignored in a keyframe + +### Keyframe references -##### References: -- https://drafts.csswg.org/css-animations/ +- ## Media Queries -A `@media` rule specifies the target media types of a set of statements. The `@media` construct allows style sheet rules that apply to various media in the same style sheet. Style rules outside of `@media` rules apply to all media types that the style sheet applies to. At-rules inside `@media` are invalid in CSS2.1. +A `@media` rule specifies the target media types of a set of statements. The +`@media` construct allows style sheet rules that apply to various media in the +same style sheet. Style rules outside of `@media` rules apply to all media types +that the style sheet applies to. At-rules inside `@media` are invalid in CSS2.1. The most basic media rule consists of specifying just a media type: + ```smalltalk CascadingStyleSheetBuilder new - declare: [ :cssBuilder | - cssBuilder - declareRuleSetFor: [ :selector | selector id: #oop ] - with: [ :style | style color: #red ] - ] - forMediaMatching: [ :queryBuilder | queryBuilder type: #print ]; - build + declare: [ :cssBuilder | + cssBuilder + declareRuleSetFor: [ :selector | selector id: #oop ] + with: [ :style | style color: #red ] + ] + forMediaMatching: [ :queryBuilder | queryBuilder type: #print ]; + build ``` -To use media queries in the library just send the message `declare:forMediaMatching:` to the builder. The first closure is evaluated with an instance of a `CascadingStyleSheetBuilder` and the second one with a builder of media queries. +To use media queries in the library just send the message +`declare:forMediaMatching:` to the builder. The first closure is evaluated with +an instance of a `CascadingStyleSheetBuilder` and the second one with a builder +of media queries. -The media query builder will match any media type by default. To specify a media type just send it the message `type:` with the corresponding media type. You can provide the following media types by keyword: -`braille`, `embossed`, `handheld`, `print`, `projection`, `screen`, `speech`, `tty` and `tv`. +The media query builder will match any media type by default. To specify a media +type just send it the message `type:` with the corresponding media type. You can +provide the following media types by keyword: +`braille`, `embossed`, `handheld`, `print`, `projection`, `screen`, `speech`, +`tty` and `tv`. -To get the list of media query constants supported inspect `RenoirSt classPool at: #CssMediaQueryConstants`. +To get the list of media query constants supported inspect +`RenoirSt classPool at: #CssMediaQueryConstants`. -The media query builder supports a variety of messages for additional conditions (called media features). Media features are used in expressions to describe requirements of the output device. +The media query builder supports a variety of messages for additional conditions +(called media features). Media features are used in expressions to describe +requirements of the output device. The following media feature messages are supported: + - Accepting a `CssMeasure` with length units - - `width:` - - `minWidth:` - - `maxWidht:` - - `height:` - - `minHeight:` - - `maxHeight:` - - `deviceWidth:` - - `minDeviceWidth:` - - `maxDeviceWidth:` - - `deviceHeight:` - - `minDeviceHeight:` - - `maxDeviceHeight:` + - `width:` + - `minWidth:` + - `maxWidht:` + - `height:` + - `minHeight:` + - `maxHeight:` + - `deviceWidth:` + - `minDeviceWidth:` + - `maxDeviceWidth:` + - `deviceHeight:` + - `minDeviceHeight:` + - `maxDeviceHeight:` - `orientation:` accepting `#portrait` or `#landscape` - Accepting fractions as aspect ratios - - `aspectRatio:` - - `minAspectRatio:` - - `maxAspectRatio:` - - `deviceAspectRatio:` - - `minDeviceAspectRatio:` - - `maxDeviceAspectRatio:` + - `aspectRatio:` + - `minAspectRatio:` + - `maxAspectRatio:` + - `deviceAspectRatio:` + - `minDeviceAspectRatio:` + - `maxDeviceAspectRatio:` - Accepting integers - - `color:` the argument describes the number of bits per color component of the output device - - `minColor:` - - `maxColor:` - - `colorIndex:` the argument describes the number of entries in the color lookup table of the output device - - `minColorIndex:` - - `maxColorIndex:` - - `monochrome:` the argument describes the number of bits per pixel in a monochrome frame buffer - - `minMonochrome:` - - `maxMonochrome:` - - `grid:` the argument must be 1 or 0 + - `color:` the argument describes the number of bits per color component of + the output device + - `minColor:` + - `maxColor:` + - `colorIndex:` the argument describes the number of entries in the color + lookup table of the output device + - `minColorIndex:` + - `maxColorIndex:` + - `monochrome:` the argument describes the number of bits per pixel in a + monochrome frame buffer + - `minMonochrome:` + - `maxMonochrome:` + - `grid:` the argument must be 1 or 0 - Accepting a `CssMeasure` with resolution units - - `resolution:` - - `minResolution:` - - `maxResolution:` + - `resolution:` + - `minResolution:` + - `maxResolution:` - `scan:` accepting `#progressive` or `#interlace` -New units for resolutions are added using the `CssMeasure` abstraction. This kind of measures can be created sending the messages `dpi` (dots per inch), `dpcm` (dots per centimeter) or `dppx` (dots per pixel unit) to an integer or float. +New units for resolutions are added using the `CssMeasure` abstraction. This +kind of measures can be created sending the messages `dpi` (dots per inch), +`dpcm` (dots per centimeter) or `dppx` (dots per pixel unit) to an integer or float. Let's see a final example to better understand the media features support: + ```smalltalk CascadingStyleSheetBuilder new - declare: [ :cssBuilder | - cssBuilder - declareRuleSetFor: [ :selector | selector id: #oop ] - with: [ :style | style color: #red ] - ] - forMediaMatching: [ :queryBuilder | - queryBuilder - orientation: #landscape; - resolution: 300 dpi - ]; - build + declare: [ :cssBuilder | + cssBuilder + declareRuleSetFor: [ :selector | selector id: #oop ] + with: [ :style | style color: #red ] + ] + forMediaMatching: [ :queryBuilder | + queryBuilder + orientation: #landscape; + resolution: 300 dpi + ]; +build ``` + Evaluates to: + ```css @media all and (orientation: landscape) and (resolution: 300dpi) { - #oop - { - color: red; - } + #oop + { + color: red; + } } ``` -##### References: -- http://www.w3.org/TR/CSS2/media.html -- http://www.w3.org/TR/css3-mediaqueries/ + +### Media Query references + +- +- ## Vendor specific extensions -The library doesn't provide out of the box support for non standard properties. However since version `1.4.0` the message `vendorPropertyAt:put:` is available to ease the creation of this kind of properties by the end user. +The library doesn't provide out of the box support for non standard properties. +However since version `1.4.0` the message `vendorPropertyAt:put:` is available +to ease the creation of this kind of properties by the end user. For example: @@ -279,80 +332,105 @@ CascadingStyleSheetBuilder new with: [:style | style vendorPropertyAt: 'crazy-margin' put: 1 px ]; build ``` + Evaluates to: + ```css div { - crazy-margin: 1px; - -moz-crazy-margin: 1px; - -webkit-crazy-margin: 1px; - -o-crazy-margin: 1px; - -ms-crazy-margin: 1px; + crazy-margin: 1px; + -moz-crazy-margin: 1px; + -webkit-crazy-margin: 1px; + -o-crazy-margin: 1px; + -ms-crazy-margin: 1px; } ``` -> **Hint:** If you really want to use a vendor specific extension, It's better to create an extension method sending the vendorPropertyAt:put: message. +> **Hint:** If you really want to use a vendor specific extension, It's better +> to create an extension method sending the vendorPropertyAt:put: message. ## Font Face Rules -The `@font-face` rule allows for linking to fonts that are automatically fetched and activated when needed. This allows authors to select a font that closely matches the design goals for a given page rather than limiting the font choice to a set of fonts available on a given platform. A set of font descriptors define the location of a font resource, either locally or externally, along with the style characteristics of an individual face. +The `@font-face` rule allows for linking to fonts that are automatically fetched +and activated when needed. This allows authors to select a font that closely +matches the design goals for a given page rather than limiting the font choice +to a set of fonts available on a given platform. A set of font descriptors +define the location of a font resource, either locally or externally, along with +the style characteristics of an individual face. This support is implemented in the builder: + ```smalltalk CascadingStyleSheetBuilder new - declareFontFaceRuleWith: [ :style | - style - fontFamily: 'Gentium'; - src: 'http://example.com/fonts/gentium.woff' asZnUrl ]; - build + declareFontFaceRuleWith: [ :style | + style + fontFamily: 'Gentium'; + src: 'http://example.com/fonts/gentium.woff' asZnUrl ]; + build ``` + renders as: + ```css @font-face { - font-family: Gentium; - src: url("http://example.com/fonts/gentium.woff"); + font-family: Gentium; + src: url("http://example.com/fonts/gentium.woff"); } ``` -This kind of rule allows for multiple `src` definitions specifying the resources containing the data. This resources can be external (fonts fetched from a URL) or local (available in the user system). This kind of resources are supported using `CssLocalFontReference` and `CssExternalFontReference`. +This kind of rule allows for multiple `src` definitions specifying the resources +containing the data. This resources can be external (fonts fetched from a URL) +or local (available in the user system). This kind of resources are supported +using `CssLocalFontReference` and `CssExternalFontReference`. Here's a more complex case showing this: + ```smalltalk CascadingStyleSheetBuilder new - declareFontFaceRuleWith: - [ :style | - style - fontFamily: 'MainText'; - src: (CssExternalFontReference locatedAt: 'gentium.eat' asZnUrl relativeToStyleSheet); - src: (CssLocalFontReference toFontNamed: 'Gentium') , (CssExternalFontReference locatedAt: 'gentium.woff' asZnUrl relativeToStyleSheet withFormat: #woff); - src: (CssExternalFontReference svgFontLocatedAt: 'fonts.svg' asZnUrl relativeToStyleSheet withId: 'simple') ]; - build + declareFontFaceRuleWith: + [ :style | + style + fontFamily: 'MainText'; + src: (CssExternalFontReference locatedAt: 'gentium.eat' asZnUrl relativeToStyleSheet); + src: (CssLocalFontReference toFontNamed: 'Gentium') , + (CssExternalFontReference locatedAt: 'gentium.woff' asZnUrl + relativeToStyleSheet withFormat: #woff); + src: (CssExternalFontReference + svgFontLocatedAt: 'fonts.svg' asZnUrl + relativeToStyleSheet withId: 'simple') ]; + build ``` ```css @font-face { - font-family: MainText; - src: url("gentium.eat"); - src: local(Gentium), url("gentium.woff") format("woff"); - src: url("fonts.svg#simple") format("svg"); + font-family: MainText; + src: url("gentium.eat"); + src: local(Gentium), url("gentium.woff") format("woff"); + src: url("fonts.svg#simple") format("svg"); } ``` -### References -- http://www.w3.org/TR/css3-fonts/#font-face-rule +### Font face references + +- ## Interaction with other frameworks and libraries ### Units -The `Units` package (available using the ConfigurationBrowser in Pharo) includes some extensions that collides with RenoirSt. Since version `1.1.0` this library is able to load automatically a compatibility package if it's loaded after `Units` package. To test this integration there's an [specific job](https://ci.inria.fr/pharo-contribution/job/RenoirSt-UnitsCompatibility/) in the contribution server, that loads first `Units` and later `RenoirSt`. -[![Build Status](https://ci.inria.fr/pharo-contribution/buildStatus/icon?job=RenoirSt-UnitsCompatibility)](https://ci.inria.fr/pharo-contribution/job/RenoirSt-UnitsCompatibility/) +The `Units` package (available using the ConfigurationBrowser in Pharo) includes +some extensions that collides with RenoirSt. Since version `1.1.0` this library +is able to load automatically a compatibility package if it's loaded after +`Units` package. ### Seaside -The library includes an optional group including some useful extensions. The [Seaside](www.seaside.st) framework includes his own class modeling URLs, when this configuration is loaded the instances of `WAUrl` can be used in the properties requiring an URI: +The library includes an optional group including some useful extensions. The +[Seaside](www.seaside.st) framework includes his own class modeling URLs, when +this configuration is loaded the instances of `WAUrl` can be used in the +properties requiring an URI: ```smalltalk CascadingStyleSheetBuilder new @@ -360,7 +438,9 @@ CascadingStyleSheetBuilder new with: [:style | style backgroundImage: 'images/logo.png' seasideUrl ]; build ``` + Evaluates to: + ```css div.logo { @@ -368,9 +448,13 @@ div.logo } ``` -This optional configuration also loads extensions to `CssDeclarationBlock` so it can be used as a `JSObject` in plugins requiring some style parameter or in `style:` methods. +This optional configuration also loads extensions to `CssDeclarationBlock` so it +can be used as a `JSObject` in plugins requiring some style parameter or in +`style:` methods. -To load this extensions you need to load in an image with Seaside already loaded the group `Deployment-Seaside-Extensions` or `Development-Seaside-Extensions` (if you want the test cases): +To load this extensions you need to load in an image with Seaside already loaded +the group `Deployment-Seaside-Extensions` or `Development-Seaside-Extensions` +(if you want the test cases): ```smalltalk Metacello new @@ -388,34 +472,36 @@ Metacello new load: 'Development-Seaside-Extensions' ``` -There's an integration job in the CI server, testing this specific configuration: [![Build Status](https://ci.inria.fr/pharo-contribution/buildStatus/icon?job=RenoirSt-SeasideExtensions)](https://ci.inria.fr/pharo-contribution/job/RenoirSt-SeasideExtensions/). - ## How to use the library from other project -Using the new Metacello API it's easy to reference the library as a dependency from another project. For example to depend on a specific version you can do something like: +Using the new Metacello API it's easy to reference the library as a dependency +from another project. For example to depend on a specific version you can do +something like: ```smalltalk ... - spec - baseline: 'RenoirSt' - with: [ spec repository: 'github://ba-st/RenoirSt:v5.0.0/source']; - import: 'RenoirSt' + spec + baseline: 'RenoirSt' + with: [ spec repository: 'github://ba-st/RenoirSt:v5.0.0/source']; + import: 'RenoirSt' ``` -you can also load specific groups, like the Seaside extensions or do pattern matching on the versions given this project uses Semantic Versioning: +you can also load specific groups, like the Seaside extensions or do pattern +matching on the versions given this project uses Semantic Versioning: ```smalltalk ... - spec - baseline: 'RenoirSt' - with: [ - spec - repository: 'github://ba-st/RenoirSt:v5/source'; - loads: #('Deployment-Seaside-Extensions')]; - import: 'RenoirSt' + spec + baseline: 'RenoirSt' + with: [ + spec + repository: 'github://ba-st/RenoirSt:v5/source'; + loads: #('Deployment-Seaside-Extensions')]; + import: 'RenoirSt' ``` The available groups are: + - Deployment: Base library (the default group) - Development: Deployment + Test cases - Deployment-Seaside-Extensions: Deployment + Seaside specific extensions diff --git a/docs/tutorial/Tutorial-TOC.md b/docs/tutorial/Tutorial-TOC.md index ea65517..84a316d 100644 --- a/docs/tutorial/Tutorial-TOC.md +++ b/docs/tutorial/Tutorial-TOC.md @@ -1,7 +1,7 @@ -Tutorial -======== +# Tutorial + +## Table Of Contents -### Table Of Contents - [Part I](Tutorial-Part-I.md) - Introduction - Basics @@ -10,10 +10,10 @@ Tutorial - Type Selectors - Combinators - Class and Id Selectors - - Attribute Selectors + - Attribute Selectors - Pseudo-Classes - Pseudo-Elements - - Selector Groups + - Selector Groups - [Part III](Tutorial-Part-III.md ) - Important Rules - Keyframes From ff5c008d2ecf05a3573a6a1d80287c781dfaefb0 Mon Sep 17 00:00:00 2001 From: Gabriel Omar Cotelli Date: Wed, 30 Jun 2021 18:15:26 -0300 Subject: [PATCH 3/4] Fix markdown lint --- CONTRIBUTING.md | 2 +- docs/tutorial/Tutorial-Part-I.md | 33 +++++++++++++++--------------- docs/tutorial/Tutorial-Part-II.md | 2 +- docs/tutorial/Tutorial-Part-III.md | 12 +++++------ 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 395b0ab..5464a09 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,7 @@ You can report issues [here](https://github.com/ba-st/RenoirSt/issues/new) 1. Download a [Pharo Image and VM](https://get.pharo.org/64) 2. Clone the project or your fork using Iceberg -3. Open the Working Copy and using the contextual menu select +3. Open the Working Copy and using the contextual menu select `Metacello -> Install baseline...` 4. Input `Development-Seaside-Extensions` 5. This will load the base code and the test cases diff --git a/docs/tutorial/Tutorial-Part-I.md b/docs/tutorial/Tutorial-Part-I.md index b42cbf0..8230088 100644 --- a/docs/tutorial/Tutorial-Part-I.md +++ b/docs/tutorial/Tutorial-Part-I.md @@ -143,7 +143,7 @@ RGB-Colors also support percentual values: ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector div ] - with: [:style | style borderColor: + with: [:style | style borderColor: (CssRGBColor red: 0 percent green: 50 percent blue: 0 percent) ]; build ``` @@ -213,7 +213,7 @@ CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector div class: 'logo' ] with: [:style | style backgroundImage: 'images/logo.png' asZnUrl ]; declareRuleSetFor: [:selector | selector div class: 'logo' ] - with: [:style | style + with: [:style | style backgroundImage: 'http://www.example.com/images/logo.png' asZnUrl ]; build ``` @@ -325,7 +325,7 @@ It's supported using the `CssToggle` abstraction. ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector unorderedList unorderedList ] - with: [:style | style listStyleType: + with: [:style | style listStyleType: (CssToggle cyclingOver: { #disc. #circle. #square}) ]; build ``` @@ -351,7 +351,7 @@ an attribute name: ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector div before ] - with: [:style | style content: + with: [:style | style content: (CssAttributeReference toAttributeNamed: 'title') ]; build ``` @@ -390,7 +390,7 @@ also it's possible to provide a fallback value in case the attribute is not pres ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector div before ] - with: [:style | style content: + with: [:style | style content: (CssAttributeReference toStringAttributeNamed: 'title' withFallback: 'Missing title') ]; build @@ -408,7 +408,7 @@ div::before ```smalltalk CascadingStyleSheetBuilder new declareRuleSetFor: [:selector | selector div before ] - with: [:style | style content: + with: [:style | style content: (CssAttributeReference toAttributeNamed: 'height' ofType: #pixel withFallback: 10 px) ]; build @@ -516,7 +516,7 @@ CascadingStyleSheetBuilder new fading: { #red. (CssColorStop for: #yellow at: 50 px). #green }) ]; declareRuleSetFor: [:selector | selector div ] with: [:style | style background: - (CssRadialGradient + (CssRadialGradient elliptical: {20 px. 30 px} at: { 20 px. 30 px} fading: { #red. #yellow. #green }) ]; @@ -538,7 +538,8 @@ div div { - background: radial-gradient(farthest-side ellipse at left bottom, red, yellow 50px, green); + background: radial-gradient(farthest-side ellipse at left bottom, red, + yellow 50px, green); } div @@ -593,7 +594,7 @@ CascadingStyleSheetBuilder new transform: (CssRotate by: 360 deg); background: #red ] ] forKeyframesNamed: 'spin'; - build + build ``` Evaluates to: @@ -732,15 +733,15 @@ An example: ```smalltalk CascadingStyleSheetBuilder new - declareRuleSetFor: [ :selector | selector div ] - with: [ :style | + declareRuleSetFor: [ :selector | selector div ] + with: [ :style | style background: #blue; animation: 'skewAnimation 5s linear infinite'; width: 100 px; height: 100 px ]; - declare: [ :cssBuilder | - cssBuilder + declare: [ :cssBuilder | + cssBuilder declareKeyframeRuleSetAt: 0 percent with: [ :style | style transform: (CssSkew by: 45 deg) ] ] forKeyframesNamed: 'skewAnimation'; @@ -790,7 +791,7 @@ CascadingStyleSheetBuilder new declareKeyframeRuleSetAt: 0 percent with: [ :style | style - transform: + transform: {(CssPerspective of: 200 px) . (CssTranslate onXAxisBy: 100 px @@ -901,7 +902,7 @@ CascadingStyleSheetBuilder new animationName: 'scale'; animationDuration: 5 s; animationTimingFunction: ( - CssCubicBezier + CssCubicBezier firstXAxis: 0.63 firstYAxis: 0.05 secondXAxis: 0.43 @@ -912,7 +913,7 @@ CascadingStyleSheetBuilder new declare: [ :cssBuilder | cssBuilder declareKeyframeRuleSetAt: 0 percent - with: [ :style | + with: [ :style | style transform: (CssScale by: 2) ]; declareKeyframeRuleSetAt: 100 percent with: [ :style | diff --git a/docs/tutorial/Tutorial-Part-II.md b/docs/tutorial/Tutorial-Part-II.md index c03c791..d7a8317 100644 --- a/docs/tutorial/Tutorial-Part-II.md +++ b/docs/tutorial/Tutorial-Part-II.md @@ -115,7 +115,7 @@ div ~ ol ```smalltalk CascadingStyleSheetBuilder new - declareRuleSetFor: [:selector | + declareRuleSetFor: [:selector | (selector div class: 'pastoral') id: #account5 ] with: [:style | style listStyleType: #lowerRoman ]; build diff --git a/docs/tutorial/Tutorial-Part-III.md b/docs/tutorial/Tutorial-Part-III.md index 0a68d0f..87cadb9 100644 --- a/docs/tutorial/Tutorial-Part-III.md +++ b/docs/tutorial/Tutorial-Part-III.md @@ -63,13 +63,13 @@ A basic keyframe rule consists of specifying just a keyframe with some style rul ```smalltalk CascadingStyleSheetBuilder new declare: [ :cssBuilder | - cssBuilder - declareKeyframeRuleSetAt: 0 percent + cssBuilder + declareKeyframeRuleSetAt: 0 percent with: [ :style | style backgroundColor: #red ]; declareKeyframeRuleSetAt: 100 percent - with: [ :style | style backgroundColor: #blue ] ] + with: [ :style | style backgroundColor: #blue ] ] forKeyframesNamed: 'example'; - build + build ``` To use keyframes in the library just send the message @@ -394,9 +394,9 @@ CascadingStyleSheetBuilder new fontFamily: 'MainText'; src: (CssExternalFontReference locatedAt: 'gentium.eat' asZnUrl relativeToStyleSheet); src: (CssLocalFontReference toFontNamed: 'Gentium') , - (CssExternalFontReference locatedAt: 'gentium.woff' asZnUrl + (CssExternalFontReference locatedAt: 'gentium.woff' asZnUrl relativeToStyleSheet withFormat: #woff); - src: (CssExternalFontReference + src: (CssExternalFontReference svgFontLocatedAt: 'fonts.svg' asZnUrl relativeToStyleSheet withId: 'simple') ]; build From 963245a01a03bcb87bb6cdb1dd0078b282b6ac7c Mon Sep 17 00:00:00 2001 From: Gabriel Omar Cotelli Date: Wed, 30 Jun 2021 18:20:14 -0300 Subject: [PATCH 4/4] Fix remaining lint --- docs/tutorial/Tutorial-Part-I.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorial/Tutorial-Part-I.md b/docs/tutorial/Tutorial-Part-I.md index 8230088..2d4fef1 100644 --- a/docs/tutorial/Tutorial-Part-I.md +++ b/docs/tutorial/Tutorial-Part-I.md @@ -792,7 +792,7 @@ CascadingStyleSheetBuilder new with: [ :style | style transform: - {(CssPerspective of: 200 px) . + {(CssPerspective of: 200 px). (CssTranslate onXAxisBy: 100 px onYAxisBy: 100 px