Skip to content
Snippets Groups Projects
Commit 90a825e0 authored by Lucas PLE's avatar Lucas PLE
Browse files

tp2

parent 756346a4
Branches master
No related tags found
No related merge requests found
{ {
"presets": ["@babel/env"] "presets": [
["@babel/env", {"modules": false}]
],
"plugins": ["@babel/plugin-proposal-class-properties"]
} }
\ No newline at end of file
{
"singleQuote": true,
"trailingComma": "es5",
"endOfLine": "lf",
"useTabs": true,
"arrowParens": "avoid"
}
{
"[javascript]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
<link rel="stylesheet" href="css/pizzaList.css"> <link rel="stylesheet" href="css/pizzaList.css">
<link rel="stylesheet" href="css/footer.css"> <link rel="stylesheet" href="css/footer.css">
<script src="build/main.js" defer></script> <script src="build/main.bundle.js" defer></script>
</head> </head>
<body> <body>
<header> <header>
......
This diff is collapsed.
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --mode=production",
"watch": "webpack --mode=development --watch"
}, },
"author": "Thomas Fritsch <thomas.fritsch@univ-lille.fr> (https://gitlab.univ-lille.fr/thomas.fritsch)", "author": "Thomas Fritsch <thomas.fritsch@univ-lille.fr> (https://gitlab.univ-lille.fr/thomas.fritsch)",
"homepage": "https://gitlab.univ-lille.fr/js", "homepage": "https://gitlab.univ-lille.fr/js",
...@@ -12,6 +14,11 @@ ...@@ -12,6 +14,11 @@
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.12.10", "@babel/cli": "^7.12.10",
"@babel/core": "^7.12.10", "@babel/core": "^7.12.10",
"@babel/preset-env": "^7.12.11" "@babel/plugin-proposal-class-properties": "^7.12.13",
"@babel/preset-env": "^7.12.11",
"babel-loader": "^8.2.2",
"prettier": "^2.2.1",
"webpack": "^5.20.1",
"webpack-cli": "^4.5.0"
} }
} }
import PizzaList from './pages/PizzaList';
class Router {
static titleElement;
static contentElement;
static routes;
static navigate(path) {
for (let i = 0; i < routes.length; i++) {
if (routes[i].path == path) {
Router.titleElement.innerHTML = new Component(
'h1',
null,
routes[i].title
);
Router.contentElement.innerHTML = new PizzaList();
}
}
}
}
export default class Component {
tagName;
children;
constructor(tagName, attribute, children) {
this.tagName = tagName;
this.attribute = attribute;
this.children = children;
}
render() {
if (this.children == null) {
return `<${this.tagName} ${this.renderAttribute()}/>`;
}
if (this.attribute == null) {
return `<${this.tagName}>${this.renderChildren()}</${this.tagName}>`;
}
return `<${
this.tagName
} ${this.renderAttribute()}>${this.renderChildren()}</${this.tagName}>`;
}
renderAttribute() {
return `${this.attribute.name}="${this.attribute.value}"`;
}
renderChildren() {
if (this.children instanceof Array) {
let result = ``;
for (let i = 0; i < this.children.length; i++) {
if (this.children[i] instanceof Component) {
result += this.children[i].render();
} else {
result += this.children[i];
}
}
return result;
}
return `${this.children}`;
}
}
import Component from './Component.js';
export default class Img extends Component {
constructor(attribute) {
super(`img`, { name: `src`, value: attribute }, null);
}
}
import Component from './Component.js';
import Img from './Img.js';
export default class PizzaThumbnail extends Component {
constructor({ name, image, price_small, price_large }) {
super('article', { name: 'class', value: 'pizzaThumbnail' }, [
new Component('a', { name: 'href', value: image }, [
new Img(image),
new Component('section', null, [
new Component('h4', null, name),
new Component('ul', null, [
new Component(
'li',
null,
`Prix petit format : ${price_small.toFixed(2)} €`
),
new Component(
'li',
null,
`Prix grand format : ${price_large.toFixed(2)} €`
),
]),
]),
]),
]);
}
}
const data = [
{
name: 'Regina',
base: 'tomate',
price_small: 6.5,
price_large: 9.95,
image:
'https://images.unsplash.com/photo-1532246420286-127bcd803104?fit=crop&w=500&h=300',
},
{
name: 'Napolitaine',
base: 'tomate',
price_small: 6.5,
price_large: 8.9,
image:
'https://images.unsplash.com/photo-1562707666-0ef112b353e0?&fit=crop&w=500&h=300',
},
{
name: 'Spicy',
base: 'crème',
price_small: 5.5,
price_large: 8,
image:
'https://images.unsplash.com/photo-1458642849426-cfb724f15ef7?fit=crop&w=500&h=300',
},
];
export default data;
// D. Manipulation des chaînes import data from './data.js';
import Component from './components/Component.js';
// const name = 'Regina'; import Img from './components/Img.js';
// const url = `images/${name.toLowerCase()}.jpg`; import PizzaThumbnail from './components/PizzaThumbnail.js';
// const html = ` import PizzaList from './pages/PizzaList.js';
// <article class="pizzaThumbnail"> import Router from './Router.js';
// <a href="${url}">
// <img src="${url}" /> const title = new Component('h1', null, ['La', ' ', 'carte']);
// <section>${name}</section> document.querySelector('.pageTitle').innerHTML = title.render();
// </a>
// </article> /*const c = new Component('article', { name: 'class', value: 'pizzaThumbnail' }, [
// `; new Img(
// document.querySelector('.pageContent').innerHTML = html; 'https://images.unsplash.com/photo-1532246420286-127bcd803104?fit=crop&w=500&h=300'
),
// // E.1. Manipulation des tableaux 'Regina',
// let data = [ 'Regina', 'Napolitaine', 'Spicy' ]; ]);
// html = ''; document.querySelector('.pageContent').innerHTML = c.render();*/
// // E.1. boucle for :
// for (let i = 0; i < data.length; i++) { /*const pizza = data[0];
// const nom = data[i], const pizzaThumbnail = new PizzaThumbnail(pizza);
// url = `images/${nom.toLowerCase()}.jpg`; document.querySelector('.pageContent').innerHTML = pizzaThumbnail.render();*/
// html += `<article class="pizzaThumbnail">
// <a href="${url}"> const pizzaList = new PizzaList(data);
// <img src="${url}" /> document.querySelector('.pageContent').innerHTML = pizzaList.render();
// <section>${nom}</section>
// </a> Router.titleElement = document.querySelector('.pageTitle');
// </article>`; Router.contentElement = document.querySelector('.pageContent');
// } Router.routes = [{ path: '/', page: pizzaList, title: 'La carte' }];
// document.querySelector('.pageContent').innerHTML = html; console.log(document.querySelector('.pageTitle'));
// E.1. Array.forEach :
// html = '';
// data.forEach( nom => {
// const url = `images/${nom.toLowerCase()}.jpg`;
// html += `<a href="${url}">
// <img src="${url}" />
// <h4>${nom}</h4>
// </a>`;
// })
// document.querySelector('.pageContent').innerHTML = html;
// // E.1. Array.map + Array.join :
// html = data.map( nom => `<a href="images/${nom.toLowerCase()}.jpg">
// <img src="images/${nom.toLowerCase()}.jpg" />
// <h4>${nom}</h4>
// </a>`).join('');
// document.querySelector('.pageContent').innerHTML = html;
// // E.1. Array.reduce :
// html = data.reduce( (str, nom) => str+`<a href="images/${nom.toLowerCase()}.jpg">
// <img src="images/${nom.toLowerCase()}.jpg" />
// <h4>${nom}</h4>
// </a>`,'');
// document.querySelector('.pageContent').innerHTML = html;
// E.2. Les objets littéraux
const data = [
{
name: 'Regina',
base: 'tomate',
price_small: 6.5,
price_large: 9.95,
image: 'https://images.unsplash.com/photo-1532246420286-127bcd803104?fit=crop&w=500&h=300'
},
{
name: 'Napolitaine',
base: 'tomate',
price_small: 6.5,
price_large: 8.95,
image: 'https://images.unsplash.com/photo-1562707666-0ef112b353e0?&fit=crop&w=500&h=300'
},
{
name: 'Spicy',
base: 'crème',
price_small: 5.5,
price_large: 8,
image: 'https://images.unsplash.com/photo-1458642849426-cfb724f15ef7?fit=crop&w=500&h=300',
}
];
function render(pizzas) {
const html = pizzas.reduce( (str, {image, name, price_small, price_large}) => str +
`<article class="pizzaThumbnail">
<a href="${image}">
<img src="${image}" />
<section>
<h4>${name}</h4>
<ul>
<li>Prix petit format : ${price_small.toFixed(2)} €</li>
<li>Prix grand format : ${price_large.toFixed(2)} €</li>
</ul>
</section>
</a>
</article>`, '');
document.querySelector('.pageContent').innerHTML = html;
}
// G.1. Tri de tableaux
function sortByName(a, b) {
if ( a.name < b.name ) {
return -1;
} else if ( a.name > b.name ) {
return 1;
}
return 0;
}
// tri par price_small croissant PUIS par price_large croissant
function sortByPrice(a, b) {
if ( a.price_small !== b.price_small ) {
return a.price_small - b.price_small;
}
return a.price_large - b.price_large;
}
// // Attention : data.sort() modifie le tableau original
render( data );
// render( data.sort(sortByName) );
// render( data.sort(sortByPrice) );
// // G.2. Système de filtre
// render( data.filter( pizza => pizza.base == 'tomate' ))
// render( data.filter( pizza => pizza.price_small < 6 ))
// // deux possibilités pour les pizzas avec deux fois la lettre "i"
// render( data.filter( pizza => pizza.name.split('i').length == 3 ))
// render( data.filter( pizza => pizza.name.match(/i/g).length == 2 ))
// // G.3. Destructuring
// render( data.filter( ({base}) => base == 'tomate' ))
// render( data.filter( ({price_small}) => price_small < 6 ))
// render( data.filter( ({name}) => name.match(/i/g).length === 2 ));
import Component from '../components/Component.js';
import PizzaThumbnail from '../components/PizzaThumbnail.js';
export default class PizzaList extends Component {
constructor(data) {
super(
'section',
{ name: 'class', value: 'pizzaList' },
data.map(function (pizza) {
return new PizzaThumbnail(pizza);
})
);
}
}
const path = require('path');
module.exports = {
// Fichier d'entrée :
entry: './src/main.js',
// Fichier de sortie :
output: {
path: path.resolve(__dirname, './build'),
filename: 'main.bundle.js',
},
// compatibilité anciens navigateurs (si besoin du support de IE11 ou android 4.4)
target: ['web', 'es5'],
// connexion webpack <-> babel :
module: {
rules: [
{
test: /\.js$/, // tous les fichiers js ...
exclude: /node_modules/, // ... sauf le dossier node_modules ...
use: {
// ... seront compilés par babel !
loader: 'babel-loader',
},
},
],
},
devtool: 'source-map',
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment