Skip to content

Commit 36cb8dd

Browse files
committed
feat: html lint and problems panel and quick view ux improvements
1 parent b062c33 commit 36cb8dd

File tree

12 files changed

+198
-21
lines changed

12 files changed

+198
-21
lines changed

docs/generatedApiDocs/utils/Metrics-API.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,15 @@ Metrics.valueEvent(Metrics.EVENT_TYPE.PERFORMANCE, "startupTime", "ms", 200);
8585
Send all pending metrics, useful before app quit.
8686
Will never throw Error.
8787

88+
## logPerformanceTime
89+
90+
Logs the performance time taken for a specific action.
91+
92+
### Parameters
93+
94+
* `action` **[string][4]** The key representing the action being measured (e.g., 'startupTime').
95+
* `durationMs` **[number][5]** The duration of the action in milliseconds.
96+
8897
[1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
8998

9099
[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function

package-lock.json

Lines changed: 10 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
"@fortawesome/fontawesome-free": "^6.1.2",
9292
"@highlightjs/cdn-assets": "^11.5.1",
9393
"@phcode/fs": "^3.0.0",
94-
"@phcode/language-support": "^1.0.7",
94+
"@phcode/language-support": "^1.1.0",
9595
"@pixelbrackets/gfm-stylesheet": "^1.1.0",
9696
"@prettier/plugin-php": "^0.22.2",
9797
"@uiw/file-icons": "^1.3.2",

src-node/live-preview.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ function _serveData(getContentAPIToUse, req, res) {
116116
...defaultHeaders,
117117
...customHeaders
118118
};
119+
if(data.textContents && !mergedHeaders['Content-Type'].includes('charset=UTF-8')) {
120+
// https://github.com/orgs/phcode-dev/discussions/1676
121+
mergedHeaders['Content-Type'] = `${mergedHeaders['Content-Type']};charset=UTF-8`;
122+
}
119123
res.writeHead(200, mergedHeaders);
120124
if(data.textContents) {
121125
res.end(data.textContents);

src-node/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* GNU AGPL-3.0 License
3+
*
4+
* Copyright (c) 2021 - present core.ai . All rights reserved.
5+
* Original work Copyright (c) 2012 - 2021 Adobe Systems Incorporated. All rights reserved.
6+
*
7+
* This program is free software: you can redistribute it and/or modify it
8+
* under the terms of the GNU Affero General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful, but WITHOUT
13+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
15+
* for more details.
16+
*
17+
* You should have received a copy of the GNU Affero General Public License
18+
* along with this program. If not, see https://opensource.org/licenses/AGPL-3.0.
19+
*
20+
*/
21+
22+
// Parts of this file is adapted from https://github.com/cfjedimaster/brackets-jshint
23+
24+
/**
25+
* Provides JSLint results via the core linting extension point
26+
*/
27+
define(function (require, exports, module) {
28+
29+
// Load dependent modules
30+
const CodeInspection = brackets.getModule("language/CodeInspection"),
31+
Strings = brackets.getModule("strings"),
32+
EditorManager = brackets.getModule("editor/EditorManager"),
33+
IndexingWorker = brackets.getModule("worker/IndexingWorker");
34+
35+
IndexingWorker.loadScriptInWorker(`${module.uri}/../worker/html-worker.js`);
36+
37+
function getTypeFromSeverity(sev) {
38+
// https://html-validate.org/guide/api/getting-started.html
39+
switch (sev) {
40+
case 1: return CodeInspection.Type.WARNING;
41+
case 2: return CodeInspection.Type.ERROR;
42+
default: return CodeInspection.Type.META;
43+
}
44+
}
45+
46+
/**
47+
* Run JSLint on the current document. Reports results to the main UI. Displays
48+
* a gold star when no errors are found.
49+
*/
50+
async function lintOneFile(text, fullPath) {
51+
return new Promise((resolve, reject)=>{
52+
IndexingWorker.execPeer("htmlLint", {
53+
text,
54+
filePath: fullPath
55+
}).then(lintResult =>{
56+
const editor = EditorManager.getActiveEditor();
57+
if(!editor || editor.document.file.fullPath !== fullPath) {
58+
reject(new Error("Lint failed as "+ Phoenix.app.getDisplayLocation(fullPath) + " is not active."));
59+
return;
60+
}
61+
if (lintResult && lintResult.length) {
62+
lintResult = lintResult.map(function (lintError) {
63+
return {
64+
pos: editor.posFromIndex(lintError.start),
65+
endPos: editor.posFromIndex(lintError.end),
66+
message: `${lintError.message} (${lintError.ruleId})`,
67+
type: getTypeFromSeverity(lintError.severity),
68+
moreInfoURL: lintError.ruleUrl
69+
};
70+
});
71+
72+
resolve({ errors: lintResult });
73+
}
74+
resolve();
75+
});
76+
});
77+
}
78+
79+
CodeInspection.register("html", {
80+
name: Strings.HTML_LINT_NAME,
81+
scanFileAsync: lintOneFile,
82+
canInspect: function (_fullPath) {
83+
return true; // no restrictions for now
84+
}
85+
});
86+
});

src/extensions/default/HTMLCodeHints/main.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ define(function (require, exports, module) {
4040
HTMLTemplate = require("text!template.html"),
4141
XHTMLTemplate = require("text!template.xhtml");
4242

43+
require("./html-lint");
44+
4345
let tags,
4446
attributes;
4547

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* GNU AGPL-3.0 License
3+
*
4+
* Copyright (c) 2021 - present core.ai . All rights reserved.
5+
*
6+
* This program is free software: you can redistribute it and/or modify it
7+
* under the terms of the GNU Affero General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
14+
* for more details.
15+
*
16+
* You should have received a copy of the GNU Affero General Public License
17+
* along with this program. If not, see https://opensource.org/licenses/AGPL-3.0.
18+
*
19+
*/
20+
21+
/*global WorkerComm, HTMLLanguageService*/
22+
23+
(function () {
24+
let htmlValidator = HTMLLanguageService.createHTMLValidator({
25+
extends: ["html-validate:standard"]
26+
});
27+
async function htmlLint(params) {
28+
const validatorResult = await htmlValidator.validateString(params.text, params.filePath);
29+
if(!validatorResult || !validatorResult.results || !validatorResult.results.length){
30+
return [];
31+
}
32+
const errors = [];
33+
for(let result of validatorResult.results){
34+
if(result.messages && result.messages.length) {
35+
for(let message of result.messages){
36+
errors.push({
37+
start: message.offset,
38+
end: message.offset + (message.size || 1) - 1,
39+
severity: message.severity,
40+
message: message.message,
41+
ruleId: message.ruleId,
42+
ruleUrl: message.ruleUrl // this is a doc link for the ruleId config, not good to show
43+
// to a user who doesnt know about html validator config is.
44+
});
45+
}
46+
}
47+
}
48+
return errors;
49+
}
50+
51+
WorkerComm.setExecHandler("htmlLint", htmlLint);
52+
}());

src/extensions/default/JSLint/ESLint.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ define(function (require, exports, module) {
114114
}
115115
};
116116
}
117+
// todo , the results have a set of suggestion suggestions which we can display to user as a set of
118+
// suggestions for a line.
117119
return {
118120
pos: { line: _0Based(lintError.line), ch: _0Based(lintError.column)},
119121
endPos: {

src/extensionsIntegrated/Phoenix-live-preview/BrowserStaticServer.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ define(function (require, exports, module) {
477477
let html = Mustache.render(markdownHTMLTemplate, templateVars);
478478
resolve({
479479
contents: html,
480-
headers: {'Content-Type': 'text/html'},
480+
headers: {'Content-Type': 'text/html; charset=UTF-8'},
481481
path: fullPath
482482
});
483483
})
@@ -627,6 +627,12 @@ define(function (require, exports, module) {
627627
// headers: {'Content-Type': 'text/html'} // optional headers
628628
response.type = 'REQUEST_RESPONSE';
629629
response.requestID = requestID;
630+
if(typeof response.contents === "string"){
631+
// https://github.com/orgs/phcode-dev/discussions/1676
632+
response.headers = {
633+
'Content-Type': 'text/html;charset=UTF-8'
634+
};
635+
}
630636
messageToLivePreviewTabs(response);
631637
})
632638
.catch(console.error);

0 commit comments

Comments
 (0)