1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | var fs_1 = require("fs");
|
4 | var path_1 = require("path");
|
5 | var Constants = require("./util/constants");
|
6 | var interfaces_1 = require("./util/interfaces");
|
7 | var helpers_1 = require("./util/helpers");
|
8 | var logger_1 = require("./logger/logger");
|
9 | function templateUpdate(changedFiles, context) {
|
10 | try {
|
11 | var changedTemplates = changedFiles.filter(function (changedFile) { return changedFile.ext === '.html'; });
|
12 | var start = Date.now();
|
13 | var bundleFiles = context.fileCache.getAll().filter(function (file) { return file.path.indexOf(context.buildDir) >= 0 && path_1.extname(file.path) === '.js'; });
|
14 |
|
15 |
|
16 | for (var _i = 0, changedTemplates_1 = changedTemplates; _i < changedTemplates_1.length; _i++) {
|
17 | var changedTemplateFile = changedTemplates_1[_i];
|
18 | var file = context.fileCache.get(changedTemplateFile.filePath);
|
19 | if (!updateCorrespondingJsFile(context, file.content, changedTemplateFile.filePath)) {
|
20 | throw new Error("Failed to inline template " + changedTemplateFile.filePath);
|
21 | }
|
22 |
|
23 | for (var _a = 0, bundleFiles_1 = bundleFiles; _a < bundleFiles_1.length; _a++) {
|
24 | var bundleFile = bundleFiles_1[_a];
|
25 | var newContent = replaceExistingJsTemplate(bundleFile.content, file.content, changedTemplateFile.filePath);
|
26 | if (newContent && newContent !== bundleFile.content) {
|
27 | context.fileCache.set(bundleFile.path, { path: bundleFile.path, content: newContent });
|
28 | fs_1.writeFileSync(bundleFile.path, newContent);
|
29 | }
|
30 | }
|
31 | }
|
32 |
|
33 | var logger = new logger_1.Logger("template update");
|
34 | logger.setStartTime(start);
|
35 |
|
36 | changedTemplates.forEach(function (changedTemplate) {
|
37 | logger_1.Logger.debug("templateUpdate, updated: " + changedTemplate.filePath);
|
38 | });
|
39 | context.templateState = interfaces_1.BuildState.SuccessfulBuild;
|
40 | logger.finish();
|
41 | return Promise.resolve();
|
42 | }
|
43 | catch (ex) {
|
44 | logger_1.Logger.debug("templateUpdate error: " + ex.message);
|
45 | context.transpileState = interfaces_1.BuildState.RequiresBuild;
|
46 | context.deepLinkState = interfaces_1.BuildState.RequiresBuild;
|
47 | context.bundleState = interfaces_1.BuildState.RequiresUpdate;
|
48 | return Promise.resolve();
|
49 | }
|
50 | }
|
51 | exports.templateUpdate = templateUpdate;
|
52 | function updateCorrespondingJsFile(context, newTemplateContent, existingHtmlTemplatePath) {
|
53 | var moduleFileExtension = helpers_1.changeExtension(helpers_1.getStringPropertyValue(Constants.ENV_NG_MODULE_FILE_NAME_SUFFIX), '.js');
|
54 | var javascriptFiles = context.fileCache.getAll().filter(function (file) { return path_1.dirname(file.path) === path_1.dirname(existingHtmlTemplatePath) && path_1.extname(file.path) === '.js' && !file.path.endsWith(moduleFileExtension); });
|
55 | for (var _i = 0, javascriptFiles_1 = javascriptFiles; _i < javascriptFiles_1.length; _i++) {
|
56 | var javascriptFile = javascriptFiles_1[_i];
|
57 | var newContent = replaceExistingJsTemplate(javascriptFile.content, newTemplateContent, existingHtmlTemplatePath);
|
58 | if (newContent && newContent !== javascriptFile.content) {
|
59 | javascriptFile.content = newContent;
|
60 |
|
61 |
|
62 | context.fileCache.set(javascriptFile.path, javascriptFile);
|
63 | var typescriptFilePath = helpers_1.changeExtension(javascriptFile.path, '.ts');
|
64 | context.fileCache.set(typescriptFilePath, context.fileCache.get(typescriptFilePath));
|
65 | return true;
|
66 | }
|
67 | }
|
68 | return false;
|
69 | }
|
70 | function inlineTemplate(sourceText, sourcePath) {
|
71 | var componentDir = path_1.parse(sourcePath).dir;
|
72 | var match;
|
73 | var replacement;
|
74 | var lastMatch = null;
|
75 | while (match = getTemplateMatch(sourceText)) {
|
76 | if (match.component === lastMatch) {
|
77 |
|
78 | logger_1.Logger.debug("Error matching component: " + match.component);
|
79 | return sourceText;
|
80 | }
|
81 | lastMatch = match.component;
|
82 | if (match.templateUrl === '') {
|
83 | logger_1.Logger.error("Error @Component templateUrl missing in: \"" + sourcePath + "\"");
|
84 | return sourceText;
|
85 | }
|
86 | replacement = updateTemplate(componentDir, match);
|
87 | if (replacement) {
|
88 | sourceText = sourceText.replace(match.component, replacement);
|
89 | }
|
90 | }
|
91 | return sourceText;
|
92 | }
|
93 | exports.inlineTemplate = inlineTemplate;
|
94 | function updateTemplate(componentDir, match) {
|
95 | var htmlFilePath = path_1.join(componentDir, match.templateUrl);
|
96 | try {
|
97 | var templateContent = fs_1.readFileSync(htmlFilePath, 'utf8');
|
98 | return replaceTemplateUrl(match, htmlFilePath, templateContent);
|
99 | }
|
100 | catch (e) {
|
101 | logger_1.Logger.error("template error, \"" + htmlFilePath + "\": " + e);
|
102 | }
|
103 | return null;
|
104 | }
|
105 | exports.updateTemplate = updateTemplate;
|
106 | function replaceTemplateUrl(match, htmlFilePath, templateContent) {
|
107 | var orgTemplateProperty = match.templateProperty;
|
108 | var newTemplateProperty = getTemplateFormat(htmlFilePath, templateContent);
|
109 | return match.component.replace(orgTemplateProperty, newTemplateProperty);
|
110 | }
|
111 | exports.replaceTemplateUrl = replaceTemplateUrl;
|
112 | function replaceExistingJsTemplate(existingSourceText, newTemplateContent, htmlFilePath) {
|
113 | var prefix = getTemplatePrefix(htmlFilePath);
|
114 | var startIndex = existingSourceText.indexOf(prefix);
|
115 | var isStringified = false;
|
116 | if (startIndex === -1) {
|
117 | prefix = stringify(prefix);
|
118 | isStringified = true;
|
119 | }
|
120 | startIndex = existingSourceText.indexOf(prefix);
|
121 | if (startIndex === -1) {
|
122 | return null;
|
123 | }
|
124 | var suffix = getTemplateSuffix(htmlFilePath);
|
125 | if (isStringified) {
|
126 | suffix = stringify(suffix);
|
127 | }
|
128 | var endIndex = existingSourceText.indexOf(suffix, startIndex + 1);
|
129 | if (endIndex === -1) {
|
130 | return null;
|
131 | }
|
132 | var oldTemplate = existingSourceText.substring(startIndex, endIndex + suffix.length);
|
133 | var newTemplate = getTemplateFormat(htmlFilePath, newTemplateContent);
|
134 | if (isStringified) {
|
135 | newTemplate = stringify(newTemplate);
|
136 | }
|
137 | var lastChange = null;
|
138 | while (existingSourceText.indexOf(oldTemplate) > -1 && existingSourceText !== lastChange) {
|
139 | lastChange = existingSourceText = existingSourceText.replace(oldTemplate, newTemplate);
|
140 | }
|
141 | return existingSourceText;
|
142 | }
|
143 | exports.replaceExistingJsTemplate = replaceExistingJsTemplate;
|
144 | function stringify(str) {
|
145 | str = JSON.stringify(str);
|
146 | return str.substr(1, str.length - 2);
|
147 | }
|
148 | function getTemplateFormat(htmlFilePath, content) {
|
149 |
|
150 | content = content.replace(/\r|\n/g, '\\n');
|
151 | content = content.replace(/\'/g, '\\\'');
|
152 | return getTemplatePrefix(htmlFilePath) + "'" + content + "'" + getTemplateSuffix(htmlFilePath);
|
153 | }
|
154 | exports.getTemplateFormat = getTemplateFormat;
|
155 | function getTemplatePrefix(htmlFilePath) {
|
156 | return "template:/*ion-inline-start:\"" + path_1.resolve(htmlFilePath) + "\"*/";
|
157 | }
|
158 | function getTemplateSuffix(htmlFilePath) {
|
159 | return "/*ion-inline-end:\"" + path_1.resolve(htmlFilePath) + "\"*/";
|
160 | }
|
161 | function getTemplateMatch(str) {
|
162 | var match = COMPONENT_REGEX.exec(str);
|
163 | if (match) {
|
164 | return {
|
165 | start: match.index,
|
166 | end: match.index + match[0].length,
|
167 | component: match[0],
|
168 | templateProperty: match[3],
|
169 | templateUrl: match[5].trim()
|
170 | };
|
171 | }
|
172 | return null;
|
173 | }
|
174 | exports.getTemplateMatch = getTemplateMatch;
|
175 | var COMPONENT_REGEX = /Component\s*?\(\s*?(\{([\s\S]*?)(\s*templateUrl\s*:\s*(['"`])(.*?)(['"`])\s*?)([\s\S]*?)}\s*?)\)/m;
|