@silexlabs/silex 3.0.0-alpha.49 → 3.0.0-alpha.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/js/main.js +1 -1
- package/dist/plugins/server/plugins/server/GitlabConnector.d.ts +1 -7
- package/dist/plugins/server/plugins/server/GitlabConnector.js +123 -116
- package/dist/plugins/server/plugins/server/GitlabConnector.js.map +1 -1
- package/package.json +1 -1
- package/src/ts/plugins/server/GitlabConnector.ts +128 -113
- package/src/ts/server/utils/BackwardCompat.ts +530 -529
|
@@ -20,532 +20,533 @@
|
|
|
20
20
|
*
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
-
import * as Path from 'path'
|
|
24
|
-
import * as fs from 'fs'
|
|
25
|
-
|
|
26
|
-
import { Constants } from '../../constants'
|
|
27
|
-
import {
|
|
28
|
-
ElementData,
|
|
29
|
-
ElementState,
|
|
30
|
-
ElementType,
|
|
31
|
-
Link,
|
|
32
|
-
LinkType
|
|
33
|
-
} from '../../client/element-store/types'
|
|
34
|
-
import { PageData } from '../../client/page-store/types'
|
|
35
|
-
import { PersistantData } from '../../client/store/types'
|
|
36
|
-
import {
|
|
37
|
-
cleanupBefore,
|
|
38
|
-
getElementsFromDomBC,
|
|
39
|
-
getPagesFromDom,
|
|
40
|
-
getSiteFromDom,
|
|
41
|
-
writeSiteStyles,
|
|
42
|
-
writeStyles
|
|
43
|
-
} from './BackwardCompatV2.5.60'
|
|
44
|
-
import { getDomElement } from '../../client/element-store/dom'
|
|
45
|
-
import { setTagName } from '../../client/utils/dom'
|
|
46
|
-
import { writeDataToDom } from '../../client/store/dom'
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
* util function for the "fixes", @see fixes
|
|
50
|
-
*/
|
|
51
|
-
function updateLinks<T extends { link?: Link }>(items: T[]): T[] {
|
|
52
|
-
return items
|
|
53
|
-
.map((item: T) => {
|
|
54
|
-
if(!!item.link && !item.link.linkType) {
|
|
55
|
-
// add new props
|
|
56
|
-
const link: any = {
|
|
57
|
-
...item.link,
|
|
58
|
-
linkType: item.link.type as LinkType,
|
|
59
|
-
href: (item.link as any).value,
|
|
60
|
-
}
|
|
61
|
-
// remove old props
|
|
62
|
-
delete link.type
|
|
63
|
-
delete link.value
|
|
64
|
-
// return the updated element
|
|
65
|
-
return {
|
|
66
|
-
...item,
|
|
67
|
-
link,
|
|
68
|
-
}
|
|
69
|
-
} else {
|
|
70
|
-
return item
|
|
71
|
-
}
|
|
72
|
-
})
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
* class name for containers which are created with sections
|
|
77
|
-
*/
|
|
78
|
-
const SECTION_CONTAINER = 'silex-container-content'
|
|
79
|
-
|
|
80
|
-
export default class BackwardCompat {
|
|
81
|
-
private data: PersistantData = null
|
|
82
|
-
private frontEndVersion: string[]
|
|
83
|
-
private silexVersion: number[]
|
|
84
|
-
|
|
85
|
-
constructor(private rootUrl: string, rootPath = __dirname + '/../../../..') {
|
|
86
|
-
/**
|
|
87
|
-
* the version of the website is stored in the generator tag as "Silex v-X-Y-Z"
|
|
88
|
-
* we get it from package.json
|
|
89
|
-
* used for backward compat and for the static files URLs taken from //{{host}}/static/{{Y-Z}}
|
|
90
|
-
*/
|
|
91
|
-
const packageJson = JSON.parse(fs.readFileSync(Path.resolve(rootPath, 'package.json')).toString())
|
|
92
|
-
this.frontEndVersion = packageJson['version:frontend'].split('.').map((s) => parseInt(s))
|
|
93
|
-
this.silexVersion = packageJson['version:backwardcompat'].split('.').map((s) => parseInt(s))
|
|
94
|
-
|
|
95
|
-
// const components = require('../../../dist/client/libs/prodotype/components/components.json')
|
|
96
|
-
console.log(`\nStarting. Version is ${this.silexVersion} for the websites and ${this.frontEndVersion} for Silex\n`)
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// remove all tags
|
|
100
|
-
// export for tests
|
|
101
|
-
removeIfExist(doc: HTMLDocument, selector: string) {
|
|
102
|
-
Array.from(doc.querySelectorAll(selector))
|
|
103
|
-
.forEach((tag) => tag.remove())
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// remove all useless css class
|
|
107
|
-
// export for tests
|
|
108
|
-
removeUselessCSSClass(doc: HTMLDocument, className: string) {
|
|
109
|
-
Array.from(doc.querySelectorAll('.' + className))
|
|
110
|
-
.forEach((el) => el.classList.remove(className))
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
getVersion(doc): number[] {
|
|
114
|
-
// if no generator tag, create one
|
|
115
|
-
let metaNode = doc.querySelector('meta[name="generator"]')
|
|
116
|
-
if (!metaNode) {
|
|
117
|
-
metaNode = doc.createElement('meta')
|
|
118
|
-
metaNode.setAttribute('name', 'generator')
|
|
119
|
-
doc.head.appendChild(metaNode)
|
|
120
|
-
}
|
|
121
|
-
// retrieve the website version from generator tag
|
|
122
|
-
return (metaNode.getAttribute('content') || '')
|
|
123
|
-
.replace('Silex v', '')
|
|
124
|
-
.split('.')
|
|
125
|
-
.map((str) => parseInt(str, 10) || 0)
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
hasDataFile(doc): boolean {
|
|
129
|
-
return !this.hasToUpdate(this.getVersion(doc), [2, 2, 11])
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* handle backward compatibility issues
|
|
134
|
-
* Backwardcompatibility process takes place after opening a file
|
|
135
|
-
* @param {Document} doc
|
|
136
|
-
* @return {Promise} a Promise, resolve can be called with a warning message
|
|
137
|
-
*/
|
|
138
|
-
async update(doc: HTMLDocument, data: PersistantData): Promise<[string, PersistantData]> {
|
|
139
|
-
// // fix an issue when the style tag has no type, then json is "broken"
|
|
140
|
-
// const styleTag = doc.querySelector('.' + Constants.JSON_STYLE_TAG_CLASS_NAME);
|
|
141
|
-
// if (styleTag) { styleTag.type = 'text/json'; } // old versions of silex have no json at all so do nothing in that case
|
|
142
|
-
// TODO: move this to the data model (e.g. data.site.silexVersion)
|
|
143
|
-
|
|
144
|
-
// we need this.data as to2_2_11 will extract it and set it from the dom
|
|
145
|
-
this.data = data
|
|
146
|
-
|
|
147
|
-
const version = this.getVersion(doc)
|
|
148
|
-
const hasToUpdate = this.hasToUpdate(version, this.silexVersion)
|
|
149
|
-
|
|
150
|
-
// warn the user
|
|
151
|
-
if (this.amIObsolete(version, this.silexVersion)) {
|
|
152
|
-
return ['This website has been saved with a newer version of Silex. Continue at your own risks.', this.data]
|
|
153
|
-
} else if (this.hasToUpdate(version, [2, 2, 7])) {
|
|
154
|
-
return Promise.reject({
|
|
155
|
-
message: 'This website has been saved with an older version of Silex, which is not supported anymore as of March 2018. In order to convert it to a newer version, please go to <a href="https://old.silex.me">old.silex.me</a> to open and then save your website. <a href="https://github.com/silexlabs/Silex/wiki/Website-saved-with-older-version-of-Silex">More about this here</a>',
|
|
156
|
-
})
|
|
157
|
-
} else if (hasToUpdate) {
|
|
158
|
-
// convert to the latest version
|
|
159
|
-
const allActions = {
|
|
160
|
-
'2.2.8': await this.to2_2_8(version, doc),
|
|
161
|
-
'2.2.9': await this.to2_2_9(version, doc),
|
|
162
|
-
'2.2.10': await this.to2_2_10(version, doc),
|
|
163
|
-
'2.2.11': await this.to2_2_11(version, doc), // this will set this.data
|
|
164
|
-
'2.2.12': await this.to2_2_12(version, doc),
|
|
165
|
-
'2.2.13': await this.to2_2_13(version, doc),
|
|
166
|
-
'2.2.14': await this.to2_2_14(version, doc),
|
|
167
|
-
}
|
|
168
|
-
// update the static scripts to match the current server and latest version
|
|
169
|
-
this.updateStatic(doc)
|
|
170
|
-
// store the latest version
|
|
171
|
-
const metaNode = doc.querySelector('meta[name="generator"]')
|
|
172
|
-
metaNode.setAttribute('content', 'Silex v' + this.silexVersion.join('.'))
|
|
173
|
-
// apply all-time fixes
|
|
174
|
-
this.fixes(doc)
|
|
175
|
-
// build the report for the user
|
|
176
|
-
const report = Object.keys(allActions)
|
|
177
|
-
.filter((_version) => allActions[_version].length > 0)
|
|
178
|
-
.map((_version) => {
|
|
179
|
-
return `<p>Update to version ${ _version }:
|
|
180
|
-
<ul>${ allActions[_version].map((_action) => `<li class="no-list">${ _action }</li>`).join('') }</ul>
|
|
181
|
-
</p>`
|
|
182
|
-
}).join('')
|
|
183
|
-
// save data to dom for front-end.js and other scripts
|
|
184
|
-
// in case data has been changed
|
|
185
|
-
// FIXME: should not have this.data mutated but returned by update scripts
|
|
186
|
-
writeDataToDom(doc, this.data)
|
|
187
|
-
// needs to reload if silex scripts and stylesheets have been updated
|
|
188
|
-
return [`
|
|
189
|
-
<p>This website has been updated to Silex latest version.</p>
|
|
190
|
-
<p>Before you save it, please check that everything is fine. Saving it with another name could be a good idea too (menu file > save as).</p>
|
|
191
|
-
<details>
|
|
192
|
-
<summary>Details</summary>
|
|
193
|
-
<small>
|
|
194
|
-
${ report }
|
|
195
|
-
</small>
|
|
196
|
-
</details>
|
|
197
|
-
`,
|
|
198
|
-
this.data,
|
|
199
|
-
]
|
|
200
|
-
} else {
|
|
201
|
-
// update the static scripts to match the current server URL
|
|
202
|
-
this.updateStatic(doc)
|
|
203
|
-
// apply all-time fixes
|
|
204
|
-
this.fixes(doc)
|
|
205
|
-
// resolve immediately
|
|
206
|
-
return ['', this.data]
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* Check for common errors in editable html files
|
|
212
|
-
*/
|
|
213
|
-
fixes(doc: HTMLDocument) {
|
|
214
|
-
// const pages: HTMLElement[] = Array.from(doc.querySelectorAll(`.${Constants.PAGES_CONTAINER_CLASS_NAME} a[${Constants.TYPE_ATTR}="page"]`));
|
|
215
|
-
// if (pages.length > 0) {
|
|
216
|
-
// console.log('Fix error of wrong silex type for', pages.length, 'pages');
|
|
217
|
-
// pages.forEach((page) => page.setAttribute(Constants.TYPE_ATTR, Constants.TYPE_PAGE));
|
|
218
|
-
// }
|
|
219
|
-
|
|
220
|
-
// the following is a fix following the beta version of 07-2020
|
|
221
|
-
// for elements and pages:
|
|
222
|
-
// link.value becomes href
|
|
223
|
-
// link.type becomes linkType
|
|
224
|
-
this.data = {
|
|
225
|
-
site: this.data.site,
|
|
226
|
-
pages: updateLinks<PageData>(this.data.pages),
|
|
227
|
-
elements: updateLinks<ElementData>(this.data.elements),
|
|
228
|
-
}
|
|
229
|
-
// remove juery-ui at publication, in case the website has been updated before the fix of 2.6.2
|
|
230
|
-
Array.from(doc.querySelectorAll('script[src$="pageable.js"], script[src$="jquery-ui.js"]'))
|
|
231
|
-
.forEach((tag) => tag.setAttribute(Constants.ATTR_REMOVE_PUBLISH, ''))
|
|
232
|
-
// this does not work because sections can not be smaller than their content:
|
|
233
|
-
// // resizable sections
|
|
234
|
-
// this.data = {
|
|
235
|
-
// ...this.data,
|
|
236
|
-
// elements: this.data.elements
|
|
237
|
-
// .map((el) => el.type === ElementType.SECTION ? {
|
|
238
|
-
// ...el,
|
|
239
|
-
// enableResize: {
|
|
240
|
-
// bottom: true,
|
|
241
|
-
// top: true,
|
|
242
|
-
// left: false,
|
|
243
|
-
// right: false,
|
|
244
|
-
// }
|
|
245
|
-
// } : el),
|
|
246
|
-
// }
|
|
247
|
-
|
|
248
|
-
// remove pages which do not exist (was caused by a bug in deletePages, fix 2021-03)
|
|
249
|
-
// also remove css classes which are pages (was caused by a bug??)
|
|
250
|
-
this.data.elements = this.data.elements.map(el => ({
|
|
251
|
-
...el,
|
|
252
|
-
pageNames: el.pageNames.filter(name => this.data.pages.some(p => p.id === name)),
|
|
253
|
-
classList: el.classList.filter(name => !this.data.pages.some(p => p.id === name)),
|
|
254
|
-
}))
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* update the static scripts to match the current server and latest version
|
|
259
|
-
*/
|
|
260
|
-
updateStatic(doc: HTMLDocument) {
|
|
261
|
-
// update //{{host}}/2.x/... to latest version
|
|
262
|
-
Array.from(doc.querySelectorAll('[' + Constants.STATIC_ASSET_ATTR + ']'))
|
|
263
|
-
.forEach((element: HTMLElement) => {
|
|
264
|
-
const propName = element.hasAttribute('src') ? 'src' : 'href'
|
|
265
|
-
if (element.hasAttribute(propName)) {
|
|
266
|
-
const newUrl = this.getStaticResourceUrl(element[propName])
|
|
267
|
-
const oldUrl = element.getAttribute(propName)
|
|
268
|
-
if (oldUrl !== newUrl) {
|
|
269
|
-
element.setAttribute(propName, newUrl)
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
})
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* get the complete URL for the static file,
|
|
277
|
-
* * on the current Silex server
|
|
278
|
-
* * with the latest Silex version
|
|
279
|
-
*
|
|
280
|
-
* this will result in a URL on the current server, in the `/static/` folder
|
|
281
|
-
*
|
|
282
|
-
* @example `//localhost:6805/static/2.1/example/example.js` returns `//editor.silex.me/static/2.7/example/unslider.js`
|
|
283
|
-
* @example `/static/2.1/example/example.js` returns `//editor.silex.me/static/2.7/example/example.js`
|
|
284
|
-
*
|
|
285
|
-
* with the current version
|
|
286
|
-
* @param {string} url
|
|
287
|
-
* @return {string}
|
|
288
|
-
*/
|
|
289
|
-
getStaticResourceUrl(url: string): string {
|
|
290
|
-
const pathRelativeToStaticMatch = url.match(/static\/[0-9]*\.[0-9]*\/(.*)/)
|
|
291
|
-
if (pathRelativeToStaticMatch == null) {
|
|
292
|
-
console.warn('Error: could not extract the path and file name of static asset', url)
|
|
293
|
-
return url
|
|
294
|
-
}
|
|
295
|
-
const pathRelativeToStatic = pathRelativeToStaticMatch[1]
|
|
296
|
-
return `${ this.rootUrl }/static/${ this.frontEndVersion[0] }.${ this.frontEndVersion[1] }/${ pathRelativeToStatic }`
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* check if the website has been edited with a newer version of Silex
|
|
301
|
-
* @param {Array.<number>} initialVersion the website version
|
|
302
|
-
* @param {Array.<number>} targetVersion a given Silex version
|
|
303
|
-
* @return {boolean}
|
|
304
|
-
*/
|
|
305
|
-
amIObsolete(initialVersion: number[], targetVersion: number[]): boolean {
|
|
306
|
-
return !!initialVersion[2] && initialVersion[0] > targetVersion[0] ||
|
|
307
|
-
initialVersion[1] > targetVersion[1] ||
|
|
308
|
-
initialVersion[2] > targetVersion[2]
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* check if the website has to be updated for the given version of Silex
|
|
313
|
-
* @param {Array.<number>} initialVersion the website version
|
|
314
|
-
* @param {Array.<number>} targetVersion a given Silex version
|
|
315
|
-
* @return {boolean}
|
|
316
|
-
*/
|
|
317
|
-
hasToUpdate(initialVersion: number[], targetVersion: number[]): boolean {
|
|
318
|
-
return initialVersion[0] < targetVersion[0] ||
|
|
319
|
-
initialVersion[1] < targetVersion[1] ||
|
|
320
|
-
initialVersion[2] < targetVersion[2]
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
to2_2_8(version: number[], doc: HTMLDocument): Promise<string[]> {
|
|
324
|
-
return new Promise((resolve, reject) => {
|
|
325
|
-
const actions = []
|
|
326
|
-
if (this.hasToUpdate(version, [2, 2, 8])) {
|
|
327
|
-
// cleanup the hamburger menu icon
|
|
328
|
-
const menuButton = doc.querySelector('.menu-button')
|
|
329
|
-
if (menuButton) {
|
|
330
|
-
menuButton.classList.remove('paged-element', 'paged-element-hidden', 'page-page-1', 'prevent-resizable')
|
|
331
|
-
menuButton.classList.add('hide-on-desktop')
|
|
332
|
-
}
|
|
333
|
-
// give the hamburger menu a size (TODO: add to the json model too)
|
|
334
|
-
doc.querySelector('.silex-inline-styles').innerHTML += '.silex-id-hamburger-menu {width: 50px;min-height: 40px;}'
|
|
335
|
-
// pages need to have href set
|
|
336
|
-
Array.from(doc.querySelectorAll('.page-element'))
|
|
337
|
-
.forEach((el: HTMLLinkElement) => {
|
|
338
|
-
el.setAttribute('href', '#!' + el.getAttribute('id'))
|
|
339
|
-
})
|
|
340
|
-
actions.push('I fixed the mobile menu so that it is compatible with the new publication (now multiple pages are generated instead of 1 single page for the whole website).')
|
|
341
|
-
}
|
|
342
|
-
resolve(actions)
|
|
343
|
-
})
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
to2_2_9(version: number[], doc: HTMLDocument): Promise<string[]> {
|
|
347
|
-
return new Promise((resolve, reject) => {
|
|
348
|
-
const actions = []
|
|
349
|
-
if (this.hasToUpdate(version, [2, 2, 9])) {
|
|
350
|
-
// remove the hamburger menu icon
|
|
351
|
-
const menuButton = doc.querySelector('.menu-button')
|
|
352
|
-
if (menuButton) {
|
|
353
|
-
menuButton.parentElement.removeChild(menuButton)
|
|
354
|
-
actions.push(
|
|
355
|
-
'I removed the mobile menu as there is now a component for that. <a target="_blank" href="https://github.com/silexlabs/Silex/wiki/Hamburger-menu">Read more about the Hamburger Menu component here</a>.',
|
|
356
|
-
)
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
resolve(actions)
|
|
360
|
-
})
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
to2_2_10(version: number[], doc: HTMLDocument): Promise<string[]> {
|
|
364
|
-
return new Promise((resolve, reject) => {
|
|
365
|
-
const actions = []
|
|
366
|
-
if (this.hasToUpdate(version, [2, 2, 10])) {
|
|
367
|
-
// the body is a drop zone, not selectable, not draggable, resizeable
|
|
368
|
-
doc.body.classList.add(
|
|
369
|
-
Constants.PREVENT_DRAGGABLE_CLASS_NAME,
|
|
370
|
-
Constants.PREVENT_RESIZABLE_CLASS_NAME,
|
|
371
|
-
Constants.PREVENT_SELECTABLE_CLASS_NAME)
|
|
372
|
-
|
|
373
|
-
// each section background and foreground is a drop zone, not selectable, not draggable, resizeable
|
|
374
|
-
const changedSections = Array.from(doc.querySelectorAll(`.${ElementType.SECTION}`)) as HTMLElement[]
|
|
375
|
-
changedSections.forEach((el: HTMLElement) => el.classList.add(
|
|
376
|
-
Constants.PREVENT_DRAGGABLE_CLASS_NAME,
|
|
377
|
-
Constants.PREVENT_RESIZABLE_CLASS_NAME,
|
|
378
|
-
))
|
|
379
|
-
|
|
380
|
-
// we add classes to the elements so that we can tell the stage component if an element is draggable, resizeable, selectable...
|
|
381
|
-
const changedSectionsContent = Array.from(doc.querySelectorAll(`.${ElementType.SECTION}, .${ElementType.SECTION} .${SECTION_CONTAINER}`))
|
|
382
|
-
changedSectionsContent.forEach((el: HTMLElement) => el.classList.add(
|
|
383
|
-
Constants.PREVENT_DRAGGABLE_CLASS_NAME,
|
|
384
|
-
// Constants.PREVENT_RESIZABLE_LEFT_CLASS_NAME,
|
|
385
|
-
// Constants.PREVENT_RESIZABLE_RIGHT_CLASS_NAME
|
|
386
|
-
))
|
|
387
|
-
actions.push(`Changed the body and ${changedSections.length} sections with new CSS classes to <a href="https://github.com/silexlabs/stage/" target="_blank">the new stage component.</a>`)
|
|
388
|
-
|
|
389
|
-
// types are now with a "-element" suffix
|
|
390
|
-
const changedElements = Array.from(doc.querySelectorAll(`[${Constants.TYPE_ATTR}]`))
|
|
391
|
-
changedElements.forEach((el: HTMLElement) => el.setAttribute(Constants.TYPE_ATTR, el.getAttribute(Constants.TYPE_ATTR) + '-element'))
|
|
392
|
-
|
|
393
|
-
actions.push(`Updated ${ changedElements.length } elements, changed their types to match the new version of Silex.`)
|
|
394
|
-
}
|
|
395
|
-
resolve(actions)
|
|
396
|
-
})
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
to2_2_11(version: number[], doc: HTMLDocument): Promise<string[]> {
|
|
400
|
-
return new Promise((resolve, reject) => {
|
|
401
|
-
const actions = []
|
|
402
|
-
if (this.hasToUpdate(version, [2, 2, 11])) {
|
|
403
|
-
// the body is supposed to be an element too
|
|
404
|
-
doc.body.classList.add(Constants.EDITABLE_CLASS_NAME)
|
|
405
|
-
actions.push('I made the body editable.')
|
|
406
|
-
|
|
407
|
-
const oldBodyId = doc.body.getAttribute('data-silex-id')
|
|
408
|
-
if (oldBodyId !== 'body-initial') {
|
|
409
|
-
actions.push('I udpated the body class name from "' + oldBodyId + '" to "body-initial".')
|
|
410
|
-
doc.body.setAttribute('data-silex-id', 'body-initial')
|
|
411
|
-
doc.body.classList.remove(oldBodyId)
|
|
412
|
-
doc.body.classList.add('body-initial')
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
// prepare the dom
|
|
416
|
-
cleanupBefore(doc)
|
|
417
|
-
|
|
418
|
-
// import elements
|
|
419
|
-
const elements = getElementsFromDomBC(doc)
|
|
420
|
-
writeStyles(doc, elements)
|
|
421
|
-
|
|
422
|
-
// site
|
|
423
|
-
const site = getSiteFromDom(doc)
|
|
424
|
-
writeSiteStyles(doc, site)
|
|
425
|
-
|
|
426
|
-
// pages
|
|
427
|
-
const pages = getPagesFromDom(doc)
|
|
428
|
-
|
|
429
|
-
if (elements.length && pages.length && site) {
|
|
430
|
-
this.data = {
|
|
431
|
-
site,
|
|
432
|
-
pages,
|
|
433
|
-
elements,
|
|
434
|
-
}
|
|
435
|
-
this.removeIfExist(doc, 'meta[name="website-width"]')
|
|
436
|
-
this.removeIfExist(doc, 'meta[name="hostingConnector"]')
|
|
437
|
-
this.removeIfExist(doc, 'meta[name="publicationPath"]')
|
|
438
|
-
|
|
439
|
-
// remove juery-ui at publication
|
|
440
|
-
Array.from(doc.querySelectorAll('script[src$="pageable.js"], script[src$="jquery-ui.js"]'))
|
|
441
|
-
.forEach((tag) => tag.setAttribute(Constants.ATTR_REMOVE_PUBLISH, ''))
|
|
442
|
-
|
|
443
|
-
;['prevent-draggable', SECTION_CONTAINER].forEach((className) => this.removeUselessCSSClass(doc, className))
|
|
444
|
-
|
|
445
|
-
actions.push('I updated the model to the latest version of Silex.')
|
|
446
|
-
// pages
|
|
447
|
-
this.removeIfExist(doc, `.${Constants.PAGES_CONTAINER_CLASS_NAME}`)
|
|
448
|
-
actions.push('I removed the old pages system.')
|
|
449
|
-
} else {
|
|
450
|
-
console.error('Could not import site from v2.2.11', {elements, pages, site})
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
resolve(actions)
|
|
454
|
-
})
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
to2_2_12(version: number[], doc: HTMLDocument): Promise<string[]> {
|
|
458
|
-
return new Promise((resolve, reject) => {
|
|
459
|
-
const actions = []
|
|
460
|
-
if (this.hasToUpdate(version, [2, 2, 12])) {
|
|
461
|
-
// add empty metadata to the website object
|
|
462
|
-
this.data = {
|
|
463
|
-
...this.data,
|
|
464
|
-
site: {
|
|
465
|
-
...this.data.site,
|
|
466
|
-
data: {},
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
actions.push('add empty metadata to the website object')
|
|
470
|
-
// sections are now section tag
|
|
471
|
-
const changedSections = Array.from(doc.querySelectorAll(`.${ElementType.SECTION}`)) as HTMLElement[]
|
|
472
|
-
changedSections.forEach((el: HTMLElement) => setTagName(el, 'section'))
|
|
473
|
-
this.data = {
|
|
474
|
-
...this.data,
|
|
475
|
-
elements: this.data.elements
|
|
476
|
-
.map((el) => ({
|
|
477
|
-
...el,
|
|
478
|
-
tagName: getDomElement(doc, el as ElementState) ? getDomElement(doc, el as ElementState).tagName : 'DIV',
|
|
479
|
-
}))
|
|
480
|
-
}
|
|
481
|
-
actions.push('All sections have a <SECTION> tag name')
|
|
482
|
-
}
|
|
483
|
-
resolve(actions)
|
|
484
|
-
})
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
to2_2_13(version: number[], doc: HTMLDocument): Promise<string[]> {
|
|
488
|
-
return new Promise((resolve, reject) => {
|
|
489
|
-
const actions = []
|
|
490
|
-
if (this.hasToUpdate(version, [2, 2, 13])) {
|
|
491
|
-
Array.from(doc.querySelectorAll('[data-silex-href]'))
|
|
492
|
-
.forEach((tag: HTMLElement) => {
|
|
493
|
-
const newEl = setTagName(tag, 'A') as HTMLLinkElement
|
|
494
|
-
newEl.href = tag.getAttribute('data-silex-href')
|
|
495
|
-
newEl.removeAttribute('data-silex-href')
|
|
496
|
-
})
|
|
497
|
-
actions.push('Replaced old Silex links with standard HTML links.')
|
|
498
|
-
}
|
|
499
|
-
resolve(actions)
|
|
500
|
-
})
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
to2_2_14(version: number[], doc: HTMLDocument): Promise<string[]> {
|
|
504
|
-
return new Promise((resolve, reject) => {
|
|
505
|
-
const actions = []
|
|
506
|
-
if (this.hasToUpdate(version, [2, 2, 14])) {
|
|
507
|
-
// do not fix this: remove w3c warning "The type attribute is unnecessary for JavaScript resources"
|
|
508
|
-
// because silex uses script type attr in WebsiteRouter
|
|
509
|
-
// instead we remove the type at publication time in DomPublisher
|
|
510
|
-
// remove w3c warning "The type attribute for the style element is not needed and should be omitted."
|
|
511
|
-
const styles = Array.from(doc.querySelectorAll('style[type="text/css"]'))
|
|
512
|
-
if(styles.length) {
|
|
513
|
-
styles.forEach(el => el.removeAttribute('type'))
|
|
514
|
-
actions.push(`Fixed ${styles.length} w3c warning 'The type attribute for the style element is not needed and should be omitted.'`)
|
|
515
|
-
}
|
|
516
|
-
// This should not be useful (previous BC bug?)
|
|
517
|
-
// Remove empty attributes
|
|
518
|
-
// Sometimes we have style="", title=""...
|
|
519
|
-
let numEmpty = 0
|
|
520
|
-
const attrs = [
|
|
521
|
-
'href',
|
|
522
|
-
'style',
|
|
523
|
-
'rel',
|
|
524
|
-
'target',
|
|
525
|
-
'type',
|
|
526
|
-
'title',
|
|
527
|
-
]
|
|
528
|
-
attrs.forEach((attr: string) => {
|
|
529
|
-
Array.from(doc.querySelectorAll(`[${attr}]`))
|
|
530
|
-
.forEach(el => {
|
|
531
|
-
if(el.hasAttribute(attr) && el.getAttribute(attr) === '') {
|
|
532
|
-
el.removeAttribute(attr)
|
|
533
|
-
numEmpty++
|
|
534
|
-
}
|
|
535
|
-
})
|
|
536
|
-
})
|
|
537
|
-
if(numEmpty) actions.push(`Removed ${numEmpty} empty attributes (${attrs.join(', ')})`)
|
|
538
|
-
|
|
539
|
-
// This should not be useful (previous BC bug?)
|
|
540
|
-
// Remove the href attribute from non <a> tags
|
|
541
|
-
// Sometimes we have href="null" on non a tags
|
|
542
|
-
const tagsWithWrongHref = Array.from(doc.querySelectorAll('[href]:not(a, link, base)'))
|
|
543
|
-
tagsWithWrongHref.forEach(el => {
|
|
544
|
-
el.removeAttribute('href')
|
|
545
|
-
})
|
|
546
|
-
if(tagsWithWrongHref.length) actions.push(`Removed ${tagsWithWrongHref.length} href attributes on non links tags`)
|
|
547
|
-
}
|
|
548
|
-
resolve(actions)
|
|
549
|
-
})
|
|
550
|
-
}
|
|
551
|
-
}
|
|
23
|
+
//import * as Path from 'path'
|
|
24
|
+
//import * as fs from 'fs'
|
|
25
|
+
//
|
|
26
|
+
//import { Constants } from '../../constants'
|
|
27
|
+
//import {
|
|
28
|
+
// ElementData,
|
|
29
|
+
// ElementState,
|
|
30
|
+
// ElementType,
|
|
31
|
+
// Link,
|
|
32
|
+
// LinkType
|
|
33
|
+
//} from '../../client/element-store/types'
|
|
34
|
+
//import { PageData } from '../../client/page-store/types'
|
|
35
|
+
//import { PersistantData } from '../../client/store/types'
|
|
36
|
+
//import {
|
|
37
|
+
// cleanupBefore,
|
|
38
|
+
// getElementsFromDomBC,
|
|
39
|
+
// getPagesFromDom,
|
|
40
|
+
// getSiteFromDom,
|
|
41
|
+
// writeSiteStyles,
|
|
42
|
+
// writeStyles
|
|
43
|
+
//} from './BackwardCompatV2.5.60'
|
|
44
|
+
//import { getDomElement } from '../../client/element-store/dom'
|
|
45
|
+
//import { setTagName } from '../../client/utils/dom'
|
|
46
|
+
//import { writeDataToDom } from '../../client/store/dom'
|
|
47
|
+
//
|
|
48
|
+
///**
|
|
49
|
+
// * util function for the "fixes", @see fixes
|
|
50
|
+
// */
|
|
51
|
+
//function updateLinks<T extends { link?: Link }>(items: T[]): T[] {
|
|
52
|
+
// return items
|
|
53
|
+
// .map((item: T) => {
|
|
54
|
+
// if(!!item.link && !item.link.linkType) {
|
|
55
|
+
// // add new props
|
|
56
|
+
// const link: any = {
|
|
57
|
+
// ...item.link,
|
|
58
|
+
// linkType: item.link.type as LinkType,
|
|
59
|
+
// href: (item.link as any).value,
|
|
60
|
+
// }
|
|
61
|
+
// // remove old props
|
|
62
|
+
// delete link.type
|
|
63
|
+
// delete link.value
|
|
64
|
+
// // return the updated element
|
|
65
|
+
// return {
|
|
66
|
+
// ...item,
|
|
67
|
+
// link,
|
|
68
|
+
// }
|
|
69
|
+
// } else {
|
|
70
|
+
// return item
|
|
71
|
+
// }
|
|
72
|
+
// })
|
|
73
|
+
//}
|
|
74
|
+
//
|
|
75
|
+
///**
|
|
76
|
+
// * class name for containers which are created with sections
|
|
77
|
+
// */
|
|
78
|
+
//const SECTION_CONTAINER = 'silex-container-content'
|
|
79
|
+
//
|
|
80
|
+
//export default class BackwardCompat {
|
|
81
|
+
// private data: PersistantData = null
|
|
82
|
+
// private frontEndVersion: string[]
|
|
83
|
+
// private silexVersion: number[]
|
|
84
|
+
//
|
|
85
|
+
// constructor(private rootUrl: string, rootPath = __dirname + '/../../../..') {
|
|
86
|
+
// /**
|
|
87
|
+
// * the version of the website is stored in the generator tag as "Silex v-X-Y-Z"
|
|
88
|
+
// * we get it from package.json
|
|
89
|
+
// * used for backward compat and for the static files URLs taken from //{{host}}/static/{{Y-Z}}
|
|
90
|
+
// */
|
|
91
|
+
// const packageJson = JSON.parse(fs.readFileSync(Path.resolve(rootPath, 'package.json')).toString())
|
|
92
|
+
// this.frontEndVersion = packageJson['version:frontend'].split('.').map((s) => parseInt(s))
|
|
93
|
+
// this.silexVersion = packageJson['version:backwardcompat'].split('.').map((s) => parseInt(s))
|
|
94
|
+
//
|
|
95
|
+
// // const components = require('../../../dist/client/libs/prodotype/components/components.json')
|
|
96
|
+
// console.log(`\nStarting. Version is ${this.silexVersion} for the websites and ${this.frontEndVersion} for Silex\n`)
|
|
97
|
+
// }
|
|
98
|
+
//
|
|
99
|
+
// // remove all tags
|
|
100
|
+
// // export for tests
|
|
101
|
+
// removeIfExist(doc: HTMLDocument, selector: string) {
|
|
102
|
+
// Array.from(doc.querySelectorAll(selector))
|
|
103
|
+
// .forEach((tag) => tag.remove())
|
|
104
|
+
// }
|
|
105
|
+
//
|
|
106
|
+
// // remove all useless css class
|
|
107
|
+
// // export for tests
|
|
108
|
+
// removeUselessCSSClass(doc: HTMLDocument, className: string) {
|
|
109
|
+
// Array.from(doc.querySelectorAll('.' + className))
|
|
110
|
+
// .forEach((el) => el.classList.remove(className))
|
|
111
|
+
// }
|
|
112
|
+
//
|
|
113
|
+
// getVersion(doc): number[] {
|
|
114
|
+
// // if no generator tag, create one
|
|
115
|
+
// let metaNode = doc.querySelector('meta[name="generator"]')
|
|
116
|
+
// if (!metaNode) {
|
|
117
|
+
// metaNode = doc.createElement('meta')
|
|
118
|
+
// metaNode.setAttribute('name', 'generator')
|
|
119
|
+
// doc.head.appendChild(metaNode)
|
|
120
|
+
// }
|
|
121
|
+
// // retrieve the website version from generator tag
|
|
122
|
+
// return (metaNode.getAttribute('content') || '')
|
|
123
|
+
// .replace('Silex v', '')
|
|
124
|
+
// .split('.')
|
|
125
|
+
// .map((str) => parseInt(str, 10) || 0)
|
|
126
|
+
// }
|
|
127
|
+
//
|
|
128
|
+
// hasDataFile(doc): boolean {
|
|
129
|
+
// return !this.hasToUpdate(this.getVersion(doc), [2, 2, 11])
|
|
130
|
+
// }
|
|
131
|
+
//
|
|
132
|
+
// /**
|
|
133
|
+
// * handle backward compatibility issues
|
|
134
|
+
// * Backwardcompatibility process takes place after opening a file
|
|
135
|
+
// * @param {Document} doc
|
|
136
|
+
// * @return {Promise} a Promise, resolve can be called with a warning message
|
|
137
|
+
// */
|
|
138
|
+
// async update(doc: HTMLDocument, data: PersistantData): Promise<[string, PersistantData]> {
|
|
139
|
+
// // // fix an issue when the style tag has no type, then json is "broken"
|
|
140
|
+
// // const styleTag = doc.querySelector('.' + Constants.JSON_STYLE_TAG_CLASS_NAME);
|
|
141
|
+
// // if (styleTag) { styleTag.type = 'text/json'; } // old versions of silex have no json at all so do nothing in that case
|
|
142
|
+
// // TODO: move this to the data model (e.g. data.site.silexVersion)
|
|
143
|
+
//
|
|
144
|
+
// // we need this.data as to2_2_11 will extract it and set it from the dom
|
|
145
|
+
// this.data = data
|
|
146
|
+
//
|
|
147
|
+
// const version = this.getVersion(doc)
|
|
148
|
+
// const hasToUpdate = this.hasToUpdate(version, this.silexVersion)
|
|
149
|
+
//
|
|
150
|
+
// // warn the user
|
|
151
|
+
// if (this.amIObsolete(version, this.silexVersion)) {
|
|
152
|
+
// return ['This website has been saved with a newer version of Silex. Continue at your own risks.', this.data]
|
|
153
|
+
// } else if (this.hasToUpdate(version, [2, 2, 7])) {
|
|
154
|
+
// return Promise.reject({
|
|
155
|
+
// message: 'This website has been saved with an older version of Silex, which is not supported anymore as of March 2018. In order to convert it to a newer version, please go to <a href="https://old.silex.me">old.silex.me</a> to open and then save your website. <a href="https://github.com/silexlabs/Silex/wiki/Website-saved-with-older-version-of-Silex">More about this here</a>',
|
|
156
|
+
// })
|
|
157
|
+
// } else if (hasToUpdate) {
|
|
158
|
+
// // convert to the latest version
|
|
159
|
+
// const allActions = {
|
|
160
|
+
// '2.2.8': await this.to2_2_8(version, doc),
|
|
161
|
+
// '2.2.9': await this.to2_2_9(version, doc),
|
|
162
|
+
// '2.2.10': await this.to2_2_10(version, doc),
|
|
163
|
+
// '2.2.11': await this.to2_2_11(version, doc), // this will set this.data
|
|
164
|
+
// '2.2.12': await this.to2_2_12(version, doc),
|
|
165
|
+
// '2.2.13': await this.to2_2_13(version, doc),
|
|
166
|
+
// '2.2.14': await this.to2_2_14(version, doc),
|
|
167
|
+
// }
|
|
168
|
+
// // update the static scripts to match the current server and latest version
|
|
169
|
+
// this.updateStatic(doc)
|
|
170
|
+
// // store the latest version
|
|
171
|
+
// const metaNode = doc.querySelector('meta[name="generator"]')
|
|
172
|
+
// metaNode.setAttribute('content', 'Silex v' + this.silexVersion.join('.'))
|
|
173
|
+
// // apply all-time fixes
|
|
174
|
+
// this.fixes(doc)
|
|
175
|
+
// // build the report for the user
|
|
176
|
+
// const report = Object.keys(allActions)
|
|
177
|
+
// .filter((_version) => allActions[_version].length > 0)
|
|
178
|
+
// .map((_version) => {
|
|
179
|
+
// return `<p>Update to version ${ _version }:
|
|
180
|
+
// <ul>${ allActions[_version].map((_action) => `<li class="no-list">${ _action }</li>`).join('') }</ul>
|
|
181
|
+
// </p>`
|
|
182
|
+
// }).join('')
|
|
183
|
+
// // save data to dom for front-end.js and other scripts
|
|
184
|
+
// // in case data has been changed
|
|
185
|
+
// // FIXME: should not have this.data mutated but returned by update scripts
|
|
186
|
+
// writeDataToDom(doc, this.data)
|
|
187
|
+
// // needs to reload if silex scripts and stylesheets have been updated
|
|
188
|
+
// return [`
|
|
189
|
+
// <p>This website has been updated to Silex latest version.</p>
|
|
190
|
+
// <p>Before you save it, please check that everything is fine. Saving it with another name could be a good idea too (menu file > save as).</p>
|
|
191
|
+
// <details>
|
|
192
|
+
// <summary>Details</summary>
|
|
193
|
+
// <small>
|
|
194
|
+
// ${ report }
|
|
195
|
+
// </small>
|
|
196
|
+
// </details>
|
|
197
|
+
// `,
|
|
198
|
+
// this.data,
|
|
199
|
+
// ]
|
|
200
|
+
// } else {
|
|
201
|
+
// // update the static scripts to match the current server URL
|
|
202
|
+
// this.updateStatic(doc)
|
|
203
|
+
// // apply all-time fixes
|
|
204
|
+
// this.fixes(doc)
|
|
205
|
+
// // resolve immediately
|
|
206
|
+
// return ['', this.data]
|
|
207
|
+
// }
|
|
208
|
+
// }
|
|
209
|
+
//
|
|
210
|
+
// /**
|
|
211
|
+
// * Check for common errors in editable html files
|
|
212
|
+
// */
|
|
213
|
+
// fixes(doc: HTMLDocument) {
|
|
214
|
+
// // const pages: HTMLElement[] = Array.from(doc.querySelectorAll(`.${Constants.PAGES_CONTAINER_CLASS_NAME} a[${Constants.TYPE_ATTR}="page"]`));
|
|
215
|
+
// // if (pages.length > 0) {
|
|
216
|
+
// // console.log('Fix error of wrong silex type for', pages.length, 'pages');
|
|
217
|
+
// // pages.forEach((page) => page.setAttribute(Constants.TYPE_ATTR, Constants.TYPE_PAGE));
|
|
218
|
+
// // }
|
|
219
|
+
//
|
|
220
|
+
// // the following is a fix following the beta version of 07-2020
|
|
221
|
+
// // for elements and pages:
|
|
222
|
+
// // link.value becomes href
|
|
223
|
+
// // link.type becomes linkType
|
|
224
|
+
// this.data = {
|
|
225
|
+
// site: this.data.site,
|
|
226
|
+
// pages: updateLinks<PageData>(this.data.pages),
|
|
227
|
+
// elements: updateLinks<ElementData>(this.data.elements),
|
|
228
|
+
// }
|
|
229
|
+
// // remove juery-ui at publication, in case the website has been updated before the fix of 2.6.2
|
|
230
|
+
// Array.from(doc.querySelectorAll('script[src$="pageable.js"], script[src$="jquery-ui.js"]'))
|
|
231
|
+
// .forEach((tag) => tag.setAttribute(Constants.ATTR_REMOVE_PUBLISH, ''))
|
|
232
|
+
// // this does not work because sections can not be smaller than their content:
|
|
233
|
+
// // // resizable sections
|
|
234
|
+
// // this.data = {
|
|
235
|
+
// // ...this.data,
|
|
236
|
+
// // elements: this.data.elements
|
|
237
|
+
// // .map((el) => el.type === ElementType.SECTION ? {
|
|
238
|
+
// // ...el,
|
|
239
|
+
// // enableResize: {
|
|
240
|
+
// // bottom: true,
|
|
241
|
+
// // top: true,
|
|
242
|
+
// // left: false,
|
|
243
|
+
// // right: false,
|
|
244
|
+
// // }
|
|
245
|
+
// // } : el),
|
|
246
|
+
// // }
|
|
247
|
+
//
|
|
248
|
+
// // remove pages which do not exist (was caused by a bug in deletePages, fix 2021-03)
|
|
249
|
+
// // also remove css classes which are pages (was caused by a bug??)
|
|
250
|
+
// this.data.elements = this.data.elements.map(el => ({
|
|
251
|
+
// ...el,
|
|
252
|
+
// pageNames: el.pageNames.filter(name => this.data.pages.some(p => p.id === name)),
|
|
253
|
+
// classList: el.classList.filter(name => !this.data.pages.some(p => p.id === name)),
|
|
254
|
+
// }))
|
|
255
|
+
// }
|
|
256
|
+
//
|
|
257
|
+
// /**
|
|
258
|
+
// * update the static scripts to match the current server and latest version
|
|
259
|
+
// */
|
|
260
|
+
// updateStatic(doc: HTMLDocument) {
|
|
261
|
+
// // update //{{host}}/2.x/... to latest version
|
|
262
|
+
// Array.from(doc.querySelectorAll('[' + Constants.STATIC_ASSET_ATTR + ']'))
|
|
263
|
+
// .forEach((element: HTMLElement) => {
|
|
264
|
+
// const propName = element.hasAttribute('src') ? 'src' : 'href'
|
|
265
|
+
// if (element.hasAttribute(propName)) {
|
|
266
|
+
// const newUrl = this.getStaticResourceUrl(element[propName])
|
|
267
|
+
// const oldUrl = element.getAttribute(propName)
|
|
268
|
+
// if (oldUrl !== newUrl) {
|
|
269
|
+
// element.setAttribute(propName, newUrl)
|
|
270
|
+
// }
|
|
271
|
+
// }
|
|
272
|
+
// })
|
|
273
|
+
// }
|
|
274
|
+
//
|
|
275
|
+
// /**
|
|
276
|
+
// * get the complete URL for the static file,
|
|
277
|
+
// * * on the current Silex server
|
|
278
|
+
// * * with the latest Silex version
|
|
279
|
+
// *
|
|
280
|
+
// * this will result in a URL on the current server, in the `/static/` folder
|
|
281
|
+
// *
|
|
282
|
+
// * @example `//localhost:6805/static/2.1/example/example.js` returns `//editor.silex.me/static/2.7/example/unslider.js`
|
|
283
|
+
// * @example `/static/2.1/example/example.js` returns `//editor.silex.me/static/2.7/example/example.js`
|
|
284
|
+
// *
|
|
285
|
+
// * with the current version
|
|
286
|
+
// * @param {string} url
|
|
287
|
+
// * @return {string}
|
|
288
|
+
// */
|
|
289
|
+
// getStaticResourceUrl(url: string): string {
|
|
290
|
+
// const pathRelativeToStaticMatch = url.match(/static\/[0-9]*\.[0-9]*\/(.*)/)
|
|
291
|
+
// if (pathRelativeToStaticMatch == null) {
|
|
292
|
+
// console.warn('Error: could not extract the path and file name of static asset', url)
|
|
293
|
+
// return url
|
|
294
|
+
// }
|
|
295
|
+
// const pathRelativeToStatic = pathRelativeToStaticMatch[1]
|
|
296
|
+
// return `${ this.rootUrl }/static/${ this.frontEndVersion[0] }.${ this.frontEndVersion[1] }/${ pathRelativeToStatic }`
|
|
297
|
+
// }
|
|
298
|
+
//
|
|
299
|
+
// /**
|
|
300
|
+
// * check if the website has been edited with a newer version of Silex
|
|
301
|
+
// * @param {Array.<number>} initialVersion the website version
|
|
302
|
+
// * @param {Array.<number>} targetVersion a given Silex version
|
|
303
|
+
// * @return {boolean}
|
|
304
|
+
// */
|
|
305
|
+
// amIObsolete(initialVersion: number[], targetVersion: number[]): boolean {
|
|
306
|
+
// return !!initialVersion[2] && initialVersion[0] > targetVersion[0] ||
|
|
307
|
+
// initialVersion[1] > targetVersion[1] ||
|
|
308
|
+
// initialVersion[2] > targetVersion[2]
|
|
309
|
+
// }
|
|
310
|
+
//
|
|
311
|
+
// /**
|
|
312
|
+
// * check if the website has to be updated for the given version of Silex
|
|
313
|
+
// * @param {Array.<number>} initialVersion the website version
|
|
314
|
+
// * @param {Array.<number>} targetVersion a given Silex version
|
|
315
|
+
// * @return {boolean}
|
|
316
|
+
// */
|
|
317
|
+
// hasToUpdate(initialVersion: number[], targetVersion: number[]): boolean {
|
|
318
|
+
// return initialVersion[0] < targetVersion[0] ||
|
|
319
|
+
// initialVersion[1] < targetVersion[1] ||
|
|
320
|
+
// initialVersion[2] < targetVersion[2]
|
|
321
|
+
// }
|
|
322
|
+
//
|
|
323
|
+
// to2_2_8(version: number[], doc: HTMLDocument): Promise<string[]> {
|
|
324
|
+
// return new Promise((resolve, reject) => {
|
|
325
|
+
// const actions = []
|
|
326
|
+
// if (this.hasToUpdate(version, [2, 2, 8])) {
|
|
327
|
+
// // cleanup the hamburger menu icon
|
|
328
|
+
// const menuButton = doc.querySelector('.menu-button')
|
|
329
|
+
// if (menuButton) {
|
|
330
|
+
// menuButton.classList.remove('paged-element', 'paged-element-hidden', 'page-page-1', 'prevent-resizable')
|
|
331
|
+
// menuButton.classList.add('hide-on-desktop')
|
|
332
|
+
// }
|
|
333
|
+
// // give the hamburger menu a size (TODO: add to the json model too)
|
|
334
|
+
// doc.querySelector('.silex-inline-styles').innerHTML += '.silex-id-hamburger-menu {width: 50px;min-height: 40px;}'
|
|
335
|
+
// // pages need to have href set
|
|
336
|
+
// Array.from(doc.querySelectorAll('.page-element'))
|
|
337
|
+
// .forEach((el: HTMLLinkElement) => {
|
|
338
|
+
// el.setAttribute('href', '#!' + el.getAttribute('id'))
|
|
339
|
+
// })
|
|
340
|
+
// actions.push('I fixed the mobile menu so that it is compatible with the new publication (now multiple pages are generated instead of 1 single page for the whole website).')
|
|
341
|
+
// }
|
|
342
|
+
// resolve(actions)
|
|
343
|
+
// })
|
|
344
|
+
// }
|
|
345
|
+
//
|
|
346
|
+
// to2_2_9(version: number[], doc: HTMLDocument): Promise<string[]> {
|
|
347
|
+
// return new Promise((resolve, reject) => {
|
|
348
|
+
// const actions = []
|
|
349
|
+
// if (this.hasToUpdate(version, [2, 2, 9])) {
|
|
350
|
+
// // remove the hamburger menu icon
|
|
351
|
+
// const menuButton = doc.querySelector('.menu-button')
|
|
352
|
+
// if (menuButton) {
|
|
353
|
+
// menuButton.parentElement.removeChild(menuButton)
|
|
354
|
+
// actions.push(
|
|
355
|
+
// 'I removed the mobile menu as there is now a component for that. <a target="_blank" href="https://github.com/silexlabs/Silex/wiki/Hamburger-menu">Read more about the Hamburger Menu component here</a>.',
|
|
356
|
+
// )
|
|
357
|
+
// }
|
|
358
|
+
// }
|
|
359
|
+
// resolve(actions)
|
|
360
|
+
// })
|
|
361
|
+
// }
|
|
362
|
+
//
|
|
363
|
+
// to2_2_10(version: number[], doc: HTMLDocument): Promise<string[]> {
|
|
364
|
+
// return new Promise((resolve, reject) => {
|
|
365
|
+
// const actions = []
|
|
366
|
+
// if (this.hasToUpdate(version, [2, 2, 10])) {
|
|
367
|
+
// // the body is a drop zone, not selectable, not draggable, resizeable
|
|
368
|
+
// doc.body.classList.add(
|
|
369
|
+
// Constants.PREVENT_DRAGGABLE_CLASS_NAME,
|
|
370
|
+
// Constants.PREVENT_RESIZABLE_CLASS_NAME,
|
|
371
|
+
// Constants.PREVENT_SELECTABLE_CLASS_NAME)
|
|
372
|
+
//
|
|
373
|
+
// // each section background and foreground is a drop zone, not selectable, not draggable, resizeable
|
|
374
|
+
// const changedSections = Array.from(doc.querySelectorAll(`.${ElementType.SECTION}`)) as HTMLElement[]
|
|
375
|
+
// changedSections.forEach((el: HTMLElement) => el.classList.add(
|
|
376
|
+
// Constants.PREVENT_DRAGGABLE_CLASS_NAME,
|
|
377
|
+
// Constants.PREVENT_RESIZABLE_CLASS_NAME,
|
|
378
|
+
// ))
|
|
379
|
+
//
|
|
380
|
+
// // we add classes to the elements so that we can tell the stage component if an element is draggable, resizeable, selectable...
|
|
381
|
+
// const changedSectionsContent = Array.from(doc.querySelectorAll(`.${ElementType.SECTION}, .${ElementType.SECTION} .${SECTION_CONTAINER}`))
|
|
382
|
+
// changedSectionsContent.forEach((el: HTMLElement) => el.classList.add(
|
|
383
|
+
// Constants.PREVENT_DRAGGABLE_CLASS_NAME,
|
|
384
|
+
// // Constants.PREVENT_RESIZABLE_LEFT_CLASS_NAME,
|
|
385
|
+
// // Constants.PREVENT_RESIZABLE_RIGHT_CLASS_NAME
|
|
386
|
+
// ))
|
|
387
|
+
// actions.push(`Changed the body and ${changedSections.length} sections with new CSS classes to <a href="https://github.com/silexlabs/stage/" target="_blank">the new stage component.</a>`)
|
|
388
|
+
//
|
|
389
|
+
// // types are now with a "-element" suffix
|
|
390
|
+
// const changedElements = Array.from(doc.querySelectorAll(`[${Constants.TYPE_ATTR}]`))
|
|
391
|
+
// changedElements.forEach((el: HTMLElement) => el.setAttribute(Constants.TYPE_ATTR, el.getAttribute(Constants.TYPE_ATTR) + '-element'))
|
|
392
|
+
//
|
|
393
|
+
// actions.push(`Updated ${ changedElements.length } elements, changed their types to match the new version of Silex.`)
|
|
394
|
+
// }
|
|
395
|
+
// resolve(actions)
|
|
396
|
+
// })
|
|
397
|
+
// }
|
|
398
|
+
//
|
|
399
|
+
// to2_2_11(version: number[], doc: HTMLDocument): Promise<string[]> {
|
|
400
|
+
// return new Promise((resolve, reject) => {
|
|
401
|
+
// const actions = []
|
|
402
|
+
// if (this.hasToUpdate(version, [2, 2, 11])) {
|
|
403
|
+
// // the body is supposed to be an element too
|
|
404
|
+
// doc.body.classList.add(Constants.EDITABLE_CLASS_NAME)
|
|
405
|
+
// actions.push('I made the body editable.')
|
|
406
|
+
//
|
|
407
|
+
// const oldBodyId = doc.body.getAttribute('data-silex-id')
|
|
408
|
+
// if (oldBodyId !== 'body-initial') {
|
|
409
|
+
// actions.push('I udpated the body class name from "' + oldBodyId + '" to "body-initial".')
|
|
410
|
+
// doc.body.setAttribute('data-silex-id', 'body-initial')
|
|
411
|
+
// doc.body.classList.remove(oldBodyId)
|
|
412
|
+
// doc.body.classList.add('body-initial')
|
|
413
|
+
// }
|
|
414
|
+
//
|
|
415
|
+
// // prepare the dom
|
|
416
|
+
// cleanupBefore(doc)
|
|
417
|
+
//
|
|
418
|
+
// // import elements
|
|
419
|
+
// const elements = getElementsFromDomBC(doc)
|
|
420
|
+
// writeStyles(doc, elements)
|
|
421
|
+
//
|
|
422
|
+
// // site
|
|
423
|
+
// const site = getSiteFromDom(doc)
|
|
424
|
+
// writeSiteStyles(doc, site)
|
|
425
|
+
//
|
|
426
|
+
// // pages
|
|
427
|
+
// const pages = getPagesFromDom(doc)
|
|
428
|
+
//
|
|
429
|
+
// if (elements.length && pages.length && site) {
|
|
430
|
+
// this.data = {
|
|
431
|
+
// site,
|
|
432
|
+
// pages,
|
|
433
|
+
// elements,
|
|
434
|
+
// }
|
|
435
|
+
// this.removeIfExist(doc, 'meta[name="website-width"]')
|
|
436
|
+
// this.removeIfExist(doc, 'meta[name="hostingConnector"]')
|
|
437
|
+
// this.removeIfExist(doc, 'meta[name="publicationPath"]')
|
|
438
|
+
//
|
|
439
|
+
// // remove juery-ui at publication
|
|
440
|
+
// Array.from(doc.querySelectorAll('script[src$="pageable.js"], script[src$="jquery-ui.js"]'))
|
|
441
|
+
// .forEach((tag) => tag.setAttribute(Constants.ATTR_REMOVE_PUBLISH, ''))
|
|
442
|
+
//
|
|
443
|
+
// ;['prevent-draggable', SECTION_CONTAINER].forEach((className) => this.removeUselessCSSClass(doc, className))
|
|
444
|
+
//
|
|
445
|
+
// actions.push('I updated the model to the latest version of Silex.')
|
|
446
|
+
// // pages
|
|
447
|
+
// this.removeIfExist(doc, `.${Constants.PAGES_CONTAINER_CLASS_NAME}`)
|
|
448
|
+
// actions.push('I removed the old pages system.')
|
|
449
|
+
// } else {
|
|
450
|
+
// console.error('Could not import site from v2.2.11', {elements, pages, site})
|
|
451
|
+
// }
|
|
452
|
+
// }
|
|
453
|
+
// resolve(actions)
|
|
454
|
+
// })
|
|
455
|
+
// }
|
|
456
|
+
//
|
|
457
|
+
// to2_2_12(version: number[], doc: HTMLDocument): Promise<string[]> {
|
|
458
|
+
// return new Promise((resolve, reject) => {
|
|
459
|
+
// const actions = []
|
|
460
|
+
// if (this.hasToUpdate(version, [2, 2, 12])) {
|
|
461
|
+
// // add empty metadata to the website object
|
|
462
|
+
// this.data = {
|
|
463
|
+
// ...this.data,
|
|
464
|
+
// site: {
|
|
465
|
+
// ...this.data.site,
|
|
466
|
+
// data: {},
|
|
467
|
+
// }
|
|
468
|
+
// }
|
|
469
|
+
// actions.push('add empty metadata to the website object')
|
|
470
|
+
// // sections are now section tag
|
|
471
|
+
// const changedSections = Array.from(doc.querySelectorAll(`.${ElementType.SECTION}`)) as HTMLElement[]
|
|
472
|
+
// changedSections.forEach((el: HTMLElement) => setTagName(el, 'section'))
|
|
473
|
+
// this.data = {
|
|
474
|
+
// ...this.data,
|
|
475
|
+
// elements: this.data.elements
|
|
476
|
+
// .map((el) => ({
|
|
477
|
+
// ...el,
|
|
478
|
+
// tagName: getDomElement(doc, el as ElementState) ? getDomElement(doc, el as ElementState).tagName : 'DIV',
|
|
479
|
+
// }))
|
|
480
|
+
// }
|
|
481
|
+
// actions.push('All sections have a <SECTION> tag name')
|
|
482
|
+
// }
|
|
483
|
+
// resolve(actions)
|
|
484
|
+
// })
|
|
485
|
+
// }
|
|
486
|
+
//
|
|
487
|
+
// to2_2_13(version: number[], doc: HTMLDocument): Promise<string[]> {
|
|
488
|
+
// return new Promise((resolve, reject) => {
|
|
489
|
+
// const actions = []
|
|
490
|
+
// if (this.hasToUpdate(version, [2, 2, 13])) {
|
|
491
|
+
// Array.from(doc.querySelectorAll('[data-silex-href]'))
|
|
492
|
+
// .forEach((tag: HTMLElement) => {
|
|
493
|
+
// const newEl = setTagName(tag, 'A') as HTMLLinkElement
|
|
494
|
+
// newEl.href = tag.getAttribute('data-silex-href')
|
|
495
|
+
// newEl.removeAttribute('data-silex-href')
|
|
496
|
+
// })
|
|
497
|
+
// actions.push('Replaced old Silex links with standard HTML links.')
|
|
498
|
+
// }
|
|
499
|
+
// resolve(actions)
|
|
500
|
+
// })
|
|
501
|
+
// }
|
|
502
|
+
//
|
|
503
|
+
// to2_2_14(version: number[], doc: HTMLDocument): Promise<string[]> {
|
|
504
|
+
// return new Promise((resolve, reject) => {
|
|
505
|
+
// const actions = []
|
|
506
|
+
// if (this.hasToUpdate(version, [2, 2, 14])) {
|
|
507
|
+
// // do not fix this: remove w3c warning "The type attribute is unnecessary for JavaScript resources"
|
|
508
|
+
// // because silex uses script type attr in WebsiteRouter
|
|
509
|
+
// // instead we remove the type at publication time in DomPublisher
|
|
510
|
+
// // remove w3c warning "The type attribute for the style element is not needed and should be omitted."
|
|
511
|
+
// const styles = Array.from(doc.querySelectorAll('style[type="text/css"]'))
|
|
512
|
+
// if(styles.length) {
|
|
513
|
+
// styles.forEach(el => el.removeAttribute('type'))
|
|
514
|
+
// actions.push(`Fixed ${styles.length} w3c warning 'The type attribute for the style element is not needed and should be omitted.'`)
|
|
515
|
+
// }
|
|
516
|
+
// // This should not be useful (previous BC bug?)
|
|
517
|
+
// // Remove empty attributes
|
|
518
|
+
// // Sometimes we have style="", title=""...
|
|
519
|
+
// let numEmpty = 0
|
|
520
|
+
// const attrs = [
|
|
521
|
+
// 'href',
|
|
522
|
+
// 'style',
|
|
523
|
+
// 'rel',
|
|
524
|
+
// 'target',
|
|
525
|
+
// 'type',
|
|
526
|
+
// 'title',
|
|
527
|
+
// ]
|
|
528
|
+
// attrs.forEach((attr: string) => {
|
|
529
|
+
// Array.from(doc.querySelectorAll(`[${attr}]`))
|
|
530
|
+
// .forEach(el => {
|
|
531
|
+
// if(el.hasAttribute(attr) && el.getAttribute(attr) === '') {
|
|
532
|
+
// el.removeAttribute(attr)
|
|
533
|
+
// numEmpty++
|
|
534
|
+
// }
|
|
535
|
+
// })
|
|
536
|
+
// })
|
|
537
|
+
// if(numEmpty) actions.push(`Removed ${numEmpty} empty attributes (${attrs.join(', ')})`)
|
|
538
|
+
//
|
|
539
|
+
// // This should not be useful (previous BC bug?)
|
|
540
|
+
// // Remove the href attribute from non <a> tags
|
|
541
|
+
// // Sometimes we have href="null" on non a tags
|
|
542
|
+
// const tagsWithWrongHref = Array.from(doc.querySelectorAll('[href]:not(a, link, base)'))
|
|
543
|
+
// tagsWithWrongHref.forEach(el => {
|
|
544
|
+
// el.removeAttribute('href')
|
|
545
|
+
// })
|
|
546
|
+
// if(tagsWithWrongHref.length) actions.push(`Removed ${tagsWithWrongHref.length} href attributes on non links tags`)
|
|
547
|
+
// }
|
|
548
|
+
// resolve(actions)
|
|
549
|
+
// })
|
|
550
|
+
// }
|
|
551
|
+
//}
|
|
552
|
+
//
|