mirror of
https://github.com/zerobig/vscode-1c-metadata-viewer.git
synced 2024-11-21 17:56:31 +02:00
0.1.0 Предпросмотр форм
This commit is contained in:
parent
a42186394d
commit
97d0000246
@ -1,6 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
## 0.0.11
|
||||
## 0.1.0
|
||||
* [new] Предпросмотр форм
|
||||
|
||||
## 0.0.12
|
||||
* [new] Общие картинки и стили
|
||||
* [fix] Ошибка когда конфигурация или расширение поддерживает несколько языков
|
||||
|
||||
|
@ -8,10 +8,9 @@
|
||||
|
||||
![Скриншот дерева метаданных](/resources/screenshot_0.png)
|
||||
|
||||
**ВНИМАНИЕ! Следующий функционал находится в статусе 'beta'! Предоставлен исключительно в ознакомительных целях.**
|
||||
|
||||
* Открывает табличные документы в режиме просмотра.
|
||||
* Открывает формы объектов и табличные документы в режиме просмотра.
|
||||
|
||||
![Скриншот предпросмотра формы](/resources/screenshot_2.png)
|
||||
![Скриншот табличного документа](/resources/screenshot_1.png)
|
||||
|
||||
## Метаданные и модули
|
||||
|
20
package.json
20
package.json
@ -2,7 +2,7 @@
|
||||
"name": "vscode-1c-metadata-viewer",
|
||||
"displayName": "1C Metadata Viewer",
|
||||
"description": "Explore 1C:Enterprise 8 configuration in the usual way",
|
||||
"version": "0.0.12",
|
||||
"version": "0.1.0",
|
||||
"publisher": "zerobig",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@ -66,6 +66,10 @@
|
||||
"command": "metadataViewer.openForm",
|
||||
"title": "%1c-metadata-viewer.openForm.title%"
|
||||
},
|
||||
{
|
||||
"command": "metadataViewer.previewForm",
|
||||
"title": "%1c-metadata-viewer.previewForm.title%"
|
||||
},
|
||||
{
|
||||
"command": "metadataViewer.openModule",
|
||||
"title": "%1c-metadata-viewer.openModule.title%"
|
||||
@ -141,6 +145,11 @@
|
||||
"group": "bsl",
|
||||
"when": "viewItem == form"
|
||||
},
|
||||
{
|
||||
"command": "metadataViewer.previewForm",
|
||||
"group": "bsl",
|
||||
"when": "viewItem == form"
|
||||
},
|
||||
{
|
||||
"command": "metadataViewer.openModule",
|
||||
"group": "bsl",
|
||||
@ -199,7 +208,8 @@
|
||||
"vscode:prepublish": "npm run compile",
|
||||
"compile": "tsc -p ./",
|
||||
"watch": "tsc -watch -p ./",
|
||||
"lint": "eslint . --ext .ts,.tsx"
|
||||
"lint": "eslint . --ext .ts,.tsx",
|
||||
"precompile": "node node_modules/xslt3/xslt3.js -xsl:xslt/form.xsl -export:xslt/form.sef.json -t"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.11.7",
|
||||
@ -208,11 +218,13 @@
|
||||
"@typescript-eslint/eslint-plugin": "^5.30.0",
|
||||
"@typescript-eslint/parser": "^5.30.0",
|
||||
"eslint": "^8.13.0",
|
||||
"typescript": "^4.8.4"
|
||||
"typescript": "^4.8.4",
|
||||
"xslt3": "^2.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vscode/webview-ui-toolkit": "^1.1.0",
|
||||
"fast-glob": "^3.2.12",
|
||||
"fast-xml-parser": "^4.0.11"
|
||||
"fast-xml-parser": "^4.0.11",
|
||||
"saxon-js": "^2.6.0"
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
"1c-metadata-viewer.openObjectModule.title": "Open object module",
|
||||
"1c-metadata-viewer.openManagerModule.title": "Open manager module",
|
||||
"1c-metadata-viewer.openForm.title": "Open form",
|
||||
"1c-metadata-viewer.previewForm.title": "Preview form",
|
||||
"1c-metadata-viewer.openModule.title": "Open module",
|
||||
"1c-metadata-viewer.openCommandModule.title": "Open command module",
|
||||
"1c-metadata-viewer.openRecordSetModule.title": "Open record set module",
|
||||
|
@ -5,6 +5,7 @@
|
||||
"1c-metadata-viewer.openObjectModule.title": "Открыть модуль объекта",
|
||||
"1c-metadata-viewer.openManagerModule.title": "Открыть модуль менеджера",
|
||||
"1c-metadata-viewer.openForm.title": "Открыть форму",
|
||||
"1c-metadata-viewer.previewForm.title": "Предпросмотр формы",
|
||||
"1c-metadata-viewer.openModule.title": "Открыть модуль",
|
||||
"1c-metadata-viewer.openCommandModule.title": "Открыть модуль команды",
|
||||
"1c-metadata-viewer.openRecordSetModule.title": "Открыть модуль набора записей",
|
||||
|
BIN
resources/screenshot_2.png
Normal file
BIN
resources/screenshot_2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 105 KiB |
1
saxon-js.d.ts
vendored
Normal file
1
saxon-js.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
declare module "saxon-js";
|
@ -3,6 +3,7 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { MetadataView, TreeItem } from './metadataView';
|
||||
import * as fs from 'fs';
|
||||
import { FormPreviewer } from './formPreviewer';
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
vscode.commands.registerCommand('metadataViewer.openAppModule', (node: TreeItem) => {
|
||||
@ -30,6 +31,10 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
const filePath = node.path + '/Ext/Form/Module.bsl';
|
||||
OpenFile(filePath);
|
||||
});
|
||||
vscode.commands.registerCommand('metadataViewer.previewForm', (node: TreeItem) => {
|
||||
const filePath = node.path + '/Ext/Form.xml';
|
||||
PreviewForm(filePath, context.extensionUri, node.label);
|
||||
});
|
||||
vscode.commands.registerCommand('metadataViewer.openModule', (node: TreeItem) => {
|
||||
const filePath = node.path + '/Ext/Module.bsl';
|
||||
OpenFile(filePath);
|
||||
@ -80,4 +85,9 @@ function OpenFile(filePath: string) {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function PreviewForm(filePath: string, extensionUri: vscode.Uri, nodeDescription?: string | vscode.TreeItemLabel) {
|
||||
const previewer = new FormPreviewer(filePath);
|
||||
previewer.openPreview(extensionUri, nodeDescription);
|
||||
}
|
||||
|
213
src/formPreviewer.ts
Normal file
213
src/formPreviewer.ts
Normal file
@ -0,0 +1,213 @@
|
||||
import * as fs from "fs";
|
||||
import * as vscode from "vscode";
|
||||
import { XMLParser } from "fast-xml-parser";
|
||||
import * as saxonJS from 'saxon-js';
|
||||
|
||||
export class FormPreviewer {
|
||||
public static readonly viewType = "metadataViewer.formPreview";
|
||||
|
||||
private filePath: string;
|
||||
private webpanel: vscode.WebviewPanel | undefined = undefined;
|
||||
|
||||
constructor(filePath: string) {
|
||||
this.filePath = filePath;
|
||||
}
|
||||
|
||||
public async openPreview(
|
||||
extensionUri: vscode.Uri,
|
||||
title?: string | vscode.TreeItemLabel
|
||||
) {
|
||||
const openPath = vscode.Uri.file(this.filePath);
|
||||
if (fs.existsSync(this.filePath)) {
|
||||
vscode.workspace.fs.readFile(openPath).then((configXml) => {
|
||||
const parser = new XMLParser({
|
||||
ignoreAttributes: false,
|
||||
attributeNamePrefix: "$_",
|
||||
});
|
||||
let result = parser.parse(Buffer.from(configXml));
|
||||
|
||||
if (this.webpanel) {
|
||||
// TODO:
|
||||
} else {
|
||||
const previewPanel = vscode.window.createWebviewPanel(
|
||||
FormPreviewer.viewType,
|
||||
`Предпросмотр формы (${title})`,
|
||||
vscode.ViewColumn.One
|
||||
);
|
||||
this.webpanel = previewPanel;
|
||||
}
|
||||
|
||||
this.generateHtml(extensionUri, Buffer.from(configXml).toString());
|
||||
});
|
||||
} else {
|
||||
vscode.window.showInformationMessage(
|
||||
`File ${this.filePath} does not exist.`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private generateHtml(extensionUri: vscode.Uri, xml: string) {
|
||||
if (this.webpanel) {
|
||||
this.generateHTMLTemplate(this.webpanel.webview, extensionUri, xml);
|
||||
}
|
||||
}
|
||||
|
||||
private generateHTMLTemplate(
|
||||
webview: vscode.Webview,
|
||||
extensionUri: vscode.Uri,
|
||||
xml: string
|
||||
) {
|
||||
const sefUri = vscode.Uri.joinPath(extensionUri, "xslt", "form.sef.json");
|
||||
if (!fs.existsSync(sefUri.fsPath)) {
|
||||
// TODO:
|
||||
return;
|
||||
}
|
||||
|
||||
vscode.workspace.fs.readFile(sefUri).then((sef) => {
|
||||
const result = saxonJS.transform(
|
||||
{
|
||||
stylesheetText: sef,
|
||||
sourceType: "xml",
|
||||
sourceText: xml,
|
||||
destination: "serialized",
|
||||
},
|
||||
"sync"
|
||||
);
|
||||
|
||||
let html = "principalResult" in result ? result.principalResult : "";
|
||||
html = html.replace(
|
||||
"<style></style>",
|
||||
`
|
||||
<style>
|
||||
html {
|
||||
font-family: arial;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.window {
|
||||
border: solid 1px;
|
||||
max-width: 920px;
|
||||
}
|
||||
.window-header {
|
||||
height: 22px;
|
||||
background-color: #bfcddb;
|
||||
}
|
||||
.window-content {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.group {
|
||||
margin: 5px 0;
|
||||
border: dotted 0px #1e1e1e;
|
||||
position: relative;
|
||||
display: grid;
|
||||
row-gap: 2px;
|
||||
}
|
||||
.group-caption {
|
||||
display: none;
|
||||
background-color: #1e1e1e;
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
left: 3px;
|
||||
font-size: 11px;
|
||||
}
|
||||
.group-title {
|
||||
color: #009690;
|
||||
}
|
||||
.group-content {
|
||||
display: flex;
|
||||
}
|
||||
.group-vertical {
|
||||
flex-direction: column;
|
||||
}
|
||||
.element {
|
||||
display: inline-flex;
|
||||
}
|
||||
label {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.input {
|
||||
height: 25px;
|
||||
border: solid 1px #a0a0a0;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.tooltip {
|
||||
color: #807a59;
|
||||
}
|
||||
button {
|
||||
height: 26px;
|
||||
border: solid 1px #a0a0a0;
|
||||
border-radius: 3px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.tabbed {
|
||||
overflow-x: hidden; /* so we could easily hide the radio inputs */
|
||||
}
|
||||
.tabbed [type="radio"] {
|
||||
display: none;
|
||||
}
|
||||
.tabs {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
.tab > label {
|
||||
padding: 5px 10px;
|
||||
border: 1px solid #a0a0a0;
|
||||
border-bottom: none;
|
||||
}
|
||||
.tab-content {
|
||||
display: none;
|
||||
}
|
||||
/* As we cannot replace the numbers with variables or calls to element properties, the number of this selector parts is our tab count limit */
|
||||
.tabbed [type="radio"]:nth-of-type(1):checked ~ .tabs .tab:nth-of-type(1) label,
|
||||
.tabbed [type="radio"]:nth-of-type(2):checked ~ .tabs .tab:nth-of-type(2) label,
|
||||
.tabbed [type="radio"]:nth-of-type(3):checked ~ .tabs .tab:nth-of-type(3) label,
|
||||
.tabbed [type="radio"]:nth-of-type(4):checked ~ .tabs .tab:nth-of-type(4) label,
|
||||
.tabbed [type="radio"]:nth-of-type(5):checked ~ .tabs .tab:nth-of-type(5) label {
|
||||
background: #37373d;
|
||||
}
|
||||
.tabbed [type="radio"]:nth-of-type(1):checked ~ .tab-content:nth-of-type(1),
|
||||
.tabbed [type="radio"]:nth-of-type(2):checked ~ .tab-content:nth-of-type(2),
|
||||
.tabbed [type="radio"]:nth-of-type(3):checked ~ .tab-content:nth-of-type(3),
|
||||
.tabbed [type="radio"]:nth-of-type(4):checked ~ .tab-content:nth-of-type(4),
|
||||
.tabbed [type="radio"]:nth-of-type(5):checked ~ .tab-content:nth-of-type(5) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.table-wrap {
|
||||
height: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
table, th, td {
|
||||
border: 1px solid;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
thead tr th {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background: #37373d;
|
||||
}
|
||||
tbody {
|
||||
}
|
||||
th > div,
|
||||
td > div {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
</style>
|
||||
`
|
||||
);
|
||||
|
||||
html = html.replace('<br />', '<br />');
|
||||
|
||||
webview.html = html;
|
||||
});
|
||||
}
|
||||
}
|
1
xslt/form.sef.json
Normal file
1
xslt/form.sef.json
Normal file
File diff suppressed because one or more lines are too long
509
xslt/form.xsl
Normal file
509
xslt/form.xsl
Normal file
@ -0,0 +1,509 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsl:stylesheet
|
||||
version="3.0"
|
||||
xpath-default-namespace="http://v8.1c.ru/8.3/xcf/logform"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:v8="http://v8.1c.ru/8.1/data/core"
|
||||
xmlns:xr="http://v8.1c.ru/8.3/xcf/readable">
|
||||
|
||||
<xsl:output method="html" />
|
||||
|
||||
<xsl:variable name="lowercase" select="'abcdefghijklmnopqrstuvwxyzабвгдеёжзийклмнопрстуфхцчшщъыьэюя'" />
|
||||
<xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'" />
|
||||
<xsl:variable name="digits">0123456789</xsl:variable>
|
||||
|
||||
<xsl:template match="/">
|
||||
<html>
|
||||
<head>
|
||||
<style></style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="window">
|
||||
<div class="window-header">
|
||||
</div>
|
||||
<div class="window-content">
|
||||
<xsl:apply-templates select="/Form/ChildItems" />
|
||||
</div>
|
||||
</div>
|
||||
<script></script>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="ChildItems">
|
||||
<xsl:for-each select="*">
|
||||
<xsl:choose>
|
||||
<xsl:when test="name() = 'Button'">
|
||||
<xsl:apply-templates select="." />
|
||||
</xsl:when>
|
||||
<xsl:when test="name() = 'ButtonGroup'">
|
||||
<!-- TODO: -->
|
||||
</xsl:when>
|
||||
<xsl:when test="name() = 'CheckBoxField'">
|
||||
<xsl:apply-templates select="." />
|
||||
</xsl:when>
|
||||
<xsl:when test="name() = 'ColumnGroup'">
|
||||
<xsl:apply-templates select="./ChildItems" />
|
||||
</xsl:when>
|
||||
<xsl:when test="name() = 'CommandBar'">
|
||||
<xsl:apply-templates select="." />
|
||||
</xsl:when>
|
||||
<xsl:when test="name() = 'InputField'">
|
||||
<xsl:choose>
|
||||
<xsl:when test="InputField/ListChoiceMode = 'true'">
|
||||
<xsl:apply-templates select="./ChoiceList" />
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:apply-templates select="." />
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:when>
|
||||
<xsl:when test="name() = 'LabelDecoration'">
|
||||
<xsl:apply-templates select="." />
|
||||
</xsl:when>
|
||||
<xsl:when test="name() = 'LabelField'">
|
||||
<xsl:apply-templates select="." />
|
||||
</xsl:when>
|
||||
<xsl:when test="name() = 'Pages'">
|
||||
<xsl:apply-templates select="." />
|
||||
</xsl:when>
|
||||
<xsl:when test="name() = 'SearchStringAddition'">
|
||||
<!-- TODO: -->
|
||||
</xsl:when>
|
||||
<xsl:when test="name() = 'Table'">
|
||||
<xsl:apply-templates select="." />
|
||||
</xsl:when>
|
||||
<xsl:when test="name() = 'UsualGroup'">
|
||||
<xsl:apply-templates select="." />
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<div>Обработка элемента <xsl:value-of select="name()" /> не предусмотрена!</div>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="UsualGroup|CommandBar">
|
||||
<div class="group">
|
||||
<xsl:if test="Visible = 'false'">
|
||||
<xsl:attribute name="style">
|
||||
<xsl:value-of select="'display: none;'" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
<span class="group-caption"><xsl:value-of select="@name" /></span>
|
||||
<xsl:if test="name() = 'UsualGroup' and Title and (not(ShowTitle) or ShowTitle = 'true')">
|
||||
<div class="group-title">
|
||||
<xsl:value-of select="Title/v8:item/v8:content/text()" />
|
||||
</div>
|
||||
</xsl:if>
|
||||
<div>
|
||||
<xsl:attribute name="class">
|
||||
<xsl:choose>
|
||||
<xsl:when test="Group">
|
||||
<xsl:value-of select="concat('group-content', ' group-', translate(Group, $uppercase, $lowercase))" />
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="'group-content'" />
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:attribute>
|
||||
<xsl:apply-templates select="ChildItems" />
|
||||
</div>
|
||||
<!-- Tooltip группы -->
|
||||
<xsl:if test="ExtendedTooltip/Title">
|
||||
<div>
|
||||
<xsl:attribute name="class">
|
||||
<xsl:value-of select="'tooltip'" />
|
||||
</xsl:attribute>
|
||||
<xsl:sequence
|
||||
select="replace(ExtendedTooltip/Title/v8:item/v8:content/text(), '\n', '$1<br />$2')"
|
||||
/>
|
||||
</div>
|
||||
</xsl:if>
|
||||
</div>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="LabelDecoration">
|
||||
<div class="label">
|
||||
<xsl:if test="Width">
|
||||
<xsl:attribute name="style">
|
||||
<xsl:value-of select="concat('width: ', number(Width) * 10, 'px;')" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
<xsl:value-of select="Title/v8:item/v8:content/text()" />
|
||||
</div>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="Button">
|
||||
<xsl:choose>
|
||||
<xsl:when test="Type = 'Hyperlink'">
|
||||
<div class="element">
|
||||
<a href="#">
|
||||
<xsl:choose>
|
||||
<xsl:when test="Title">
|
||||
<xsl:value-of select="Title/v8:item/v8:content/text()" />
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<!-- TODO: <xsl:evaluate xpath="CommandName/text()" /> -->
|
||||
<xsl:call-template name="SplitCamelCase">
|
||||
<xsl:with-param name="text" select="@name" />
|
||||
</xsl:call-template>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</a>
|
||||
</div>
|
||||
<xsl:if test="ExtendedTooltip/Title">
|
||||
<div class="tooltip">
|
||||
<xsl:value-of select="ExtendedTooltip/Title/v8:item/v8:content/text()" />
|
||||
</div>
|
||||
</xsl:if>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:if test="not(LocationInCommandBar = 'InAdditionalSubmenu')">
|
||||
<button>
|
||||
<xsl:value-of select="@name" />
|
||||
</button>
|
||||
</xsl:if>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="InputField">
|
||||
<xsl:choose>
|
||||
<!-- Колонка таблицы -->
|
||||
<xsl:when test="../../name() = 'Table' or ../../name() = 'ColumnGroup'">
|
||||
<th>
|
||||
<xsl:if test="not(Width)">
|
||||
<xsl:attribute name="style">
|
||||
<xsl:value-of select="'width: 100%'" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
<div>
|
||||
<xsl:if test="Width">
|
||||
<xsl:attribute name="style">
|
||||
<xsl:value-of select="concat('width: ', number(Width) * 10, 'px;')" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
<xsl:value-of select="DataPath" />
|
||||
</div>
|
||||
</th>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<!-- Обычное поле формы -->
|
||||
<div class="element">
|
||||
<xsl:if test="HorizontalStretch = 'true'">
|
||||
<xsl:attribute name="style">
|
||||
<xsl:value-of select="'width: 100%'" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
<xsl:if test="not(TitleLocation = 'None')">
|
||||
<label>
|
||||
<xsl:variable name="dataPath" select="DataPath"/>
|
||||
<xsl:choose>
|
||||
<xsl:when test="Title">
|
||||
<xsl:value-of select="concat(Title/v8:item/v8:content/text(), ': ')" />
|
||||
</xsl:when>
|
||||
<xsl:when test="starts-with($dataPath, 'Объект.')">
|
||||
<xsl:value-of select="$dataPath" />
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="concat(/Form/Attributes/Attribute[@name=$dataPath]/Title/v8:item/v8:content/text(), ': ')" />
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</label>
|
||||
</xsl:if>
|
||||
<xsl:choose>
|
||||
<xsl:when test="MultiLine = 'true'">
|
||||
<textarea>
|
||||
<xsl:if test="HorizontalStretch = 'true'">
|
||||
<xsl:attribute name="style">
|
||||
<xsl:value-of select="'width: 100%'" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
<xsl:attribute name="rows">
|
||||
<xsl:value-of select="Height" />
|
||||
</xsl:attribute>
|
||||
</textarea>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<input class="input">
|
||||
<xsl:if test="InputHint">
|
||||
<xsl:attribute name="placeholder">
|
||||
<xsl:value-of select="InputHint/v8:item/v8:content" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
<xsl:choose>
|
||||
<xsl:when test="Width">
|
||||
<xsl:attribute name="style">
|
||||
<xsl:value-of select="concat('width: ', number(Width) * 10, 'px;')" />
|
||||
</xsl:attribute>
|
||||
</xsl:when>
|
||||
<xsl:when test="HorizontalStretch = 'true'">
|
||||
<xsl:attribute name="style">
|
||||
<xsl:value-of select="'width: 100%'" />
|
||||
</xsl:attribute>
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
</input>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</div>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="InputField/ChoiceList">
|
||||
<div class="element">
|
||||
<xsl:if test="not(TitleLocation = 'None')">
|
||||
<label>
|
||||
<xsl:value-of select="concat(../Title/v8:item/v8:content/text(), ': ')" />
|
||||
</label>
|
||||
</xsl:if>
|
||||
<select class="input">
|
||||
<xsl:apply-templates select="xr:Item" />
|
||||
</select>
|
||||
</div>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="xr:Item">
|
||||
<option>
|
||||
<xsl:attribute name="value">
|
||||
<xsl:value-of select="xr:Value/Value" />
|
||||
</xsl:attribute>
|
||||
<xsl:value-of select="xr:Value/Presentation/v8:item/v8:content" />
|
||||
</option>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="LabelField">
|
||||
<th>
|
||||
<xsl:if test="not(Width)">
|
||||
<xsl:attribute name="style">
|
||||
<xsl:value-of select="'width: 100%'" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
<div>
|
||||
<xsl:if test="Width">
|
||||
<xsl:attribute name="style">
|
||||
<xsl:value-of select="concat('width: ', number(Width) * 10, 'px;')" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
<xsl:value-of select="DataPath" />
|
||||
</div>
|
||||
</th>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="CheckBoxField">
|
||||
<xsl:choose>
|
||||
<!-- Колонка таблицы -->
|
||||
<xsl:when test="../../name() = 'Table' or ../../name() = 'ColumnGroup'">
|
||||
<th>
|
||||
<xsl:if test="not(Width)">
|
||||
<xsl:attribute name="style">
|
||||
<xsl:value-of select="'width: 100%'" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
<div>
|
||||
<xsl:if test="Width">
|
||||
<xsl:attribute name="style">
|
||||
<xsl:value-of select="concat('width: ', number(Width) * 10, 'px;')" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
<xsl:value-of select="DataPath" />
|
||||
</div>
|
||||
</th>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<!-- Обычное поле формы -->
|
||||
<div class="element">
|
||||
<xsl:if test="not(TitleLocation) or TitleLocation = 'Left'">
|
||||
<label>
|
||||
<xsl:choose>
|
||||
<xsl:when test="Title">
|
||||
<xsl:value-of select="Title/v8:item/v8:content/text()" />
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:call-template name="SplitCamelCase">
|
||||
<xsl:with-param name="text" select="@name" />
|
||||
</xsl:call-template>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</label>
|
||||
</xsl:if>
|
||||
<input type="checkbox" />
|
||||
<xsl:if test="TitleLocation = 'Right'">
|
||||
<label>
|
||||
<xsl:choose>
|
||||
<xsl:when test="Title">
|
||||
<xsl:value-of select="Title/v8:item/v8:content/text()" />
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:call-template name="SplitCamelCase">
|
||||
<xsl:with-param name="text" select="@name" />
|
||||
</xsl:call-template>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</label>
|
||||
</xsl:if>
|
||||
</div>
|
||||
<xsl:if test="ExtendedTooltip/Title">
|
||||
<div class="tooltip">
|
||||
<xsl:value-of select="ExtendedTooltip/Title/v8:item/v8:content/text()" />
|
||||
</div>
|
||||
</xsl:if>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="Pages">
|
||||
<div class="tabbed">
|
||||
<xsl:for-each select="ChildItems/Page">
|
||||
<xsl:call-template name="PageInput">
|
||||
<xsl:with-param name="node" select="." />
|
||||
<xsl:with-param name="position" select="position()" />
|
||||
</xsl:call-template>
|
||||
</xsl:for-each>
|
||||
<ul class="tabs">
|
||||
<xsl:for-each select="ChildItems/Page">
|
||||
<xsl:call-template name="PageLabel">
|
||||
<xsl:with-param name="node" select="." />
|
||||
<xsl:with-param name="position" select="position()" />
|
||||
</xsl:call-template>
|
||||
</xsl:for-each>
|
||||
</ul>
|
||||
<xsl:for-each select="ChildItems/Page">
|
||||
<xsl:call-template name="PageContent">
|
||||
<xsl:with-param name="node" select="." />
|
||||
</xsl:call-template>
|
||||
</xsl:for-each>
|
||||
</div>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="PageInput">
|
||||
<xsl:param name="node" />
|
||||
<xsl:param name="position" />
|
||||
|
||||
<input type="radio">
|
||||
<xsl:attribute name="id">
|
||||
<xsl:value-of select="concat('tab', $node/../../@id, '_', $position)" />
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="name">
|
||||
<xsl:value-of select="concat('tab-group', $node/../../@id)" />
|
||||
</xsl:attribute>
|
||||
<xsl:if test="$position = 1">
|
||||
<xsl:attribute name="checked">
|
||||
<xsl:value-of select="''" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
</input>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="PageLabel">
|
||||
<xsl:param name="node" />
|
||||
<xsl:param name="position" />
|
||||
|
||||
<li class="tab">
|
||||
<label>
|
||||
<xsl:attribute name="for">
|
||||
<xsl:value-of select="concat('tab', $node/../../@id, '_', $position)" />
|
||||
</xsl:attribute>
|
||||
<xsl:if test="$node/../../PagesRepresentation = 'None'">
|
||||
<xsl:attribute name="style">
|
||||
<xsl:value-of select="'display: none'" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
<xsl:value-of select="$node/Title/v8:item/v8:content/text()" />
|
||||
</label>
|
||||
</li>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="PageContent">
|
||||
<xsl:param name="node" />
|
||||
|
||||
<section class="tab-content">
|
||||
<xsl:apply-templates select="$node/ChildItems" />
|
||||
</section>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="Table">
|
||||
<xsl:if test="AutoCommandBar">
|
||||
<xsl:apply-templates select="AutoCommandBar/ChildItems" />
|
||||
</xsl:if>
|
||||
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<xsl:apply-templates select="ChildItems" />
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<xsl:call-template name="TableRows">
|
||||
<xsl:with-param name="nodes" select="ChildItems" />
|
||||
</xsl:call-template>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="TableRows">
|
||||
<xsl:param name="nodes" />
|
||||
|
||||
<xsl:for-each select="1 to 40">
|
||||
<tr>
|
||||
<xsl:for-each select="$nodes/*">
|
||||
<!-- TODO: Надо обходить ещё и ColumnGroup'ы -->
|
||||
<td>
|
||||
<div>
|
||||
<xsl:if test="Width">
|
||||
<xsl:attribute name="style">
|
||||
<xsl:value-of select="concat('width: ', number(Width) * 10, 'px;')" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
<xsl:choose>
|
||||
<xsl:when test="name() = 'CheckBoxField'">
|
||||
<input type="checkbox" />
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
 
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</div>
|
||||
</td>
|
||||
</xsl:for-each>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="SplitCamelCase">
|
||||
<xsl:param name="text" />
|
||||
<xsl:param name="digitsMode" select="0" />
|
||||
<xsl:param name="firstIteration" select="0" />
|
||||
|
||||
<xsl:if test="$text != ''">
|
||||
<xsl:variable name="letter" select="substring($text, 1, 1)" />
|
||||
<xsl:choose>
|
||||
<xsl:when test="$firstIteration != 0 and contains($uppercase, $letter)">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="translate($letter, $uppercase, $lowercase)" />
|
||||
</xsl:when>
|
||||
<xsl:when test="contains($digits, $letter)">
|
||||
<xsl:choose>
|
||||
<xsl:when test="$digitsMode != 1">
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="$letter" />
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="$letter"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:call-template name="SplitCamelCase">
|
||||
<xsl:with-param name="text" select="substring-after($text, $letter)" />
|
||||
<xsl:with-param name="digitsMode" select="contains($digits, $letter)" />
|
||||
<xsl:with-param name="firstIteration" select="1" />
|
||||
</xsl:call-template>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
Loading…
Reference in New Issue
Block a user