|
@@ -108,6 +108,8 @@ class ClassPage {
|
|
|
PropertyItem: 'property-item'
|
|
|
};
|
|
|
|
|
|
+ static __static__ = '__static__';
|
|
|
+
|
|
|
start() {
|
|
|
if(typeof Class === 'string') {
|
|
|
return this;
|
|
@@ -307,6 +309,9 @@ class ClassPage {
|
|
|
|
|
|
// TODO: refactor! Make PropertyItem class
|
|
|
renderPropertiesType(properties, type, headerText, container, initiallyHidden, isMethods) {
|
|
|
+ const isStatics = type === ClassPage.PropertyType.Statics;
|
|
|
+ const isInherited = type === ClassPage.PropertyType.Inherited;
|
|
|
+
|
|
|
properties = properties[type];
|
|
|
|
|
|
if(!properties || properties.length == 0)
|
|
@@ -325,7 +330,7 @@ class ClassPage {
|
|
|
|| element.getTag() === DOM.Tags.A;
|
|
|
};
|
|
|
|
|
|
- if(type !== ClassPage.PropertyType.Inherited) {
|
|
|
+ if(!isInherited) {
|
|
|
this.documentable += properties.length;
|
|
|
} else {
|
|
|
const inheritedCommentsQuery = this.inheritedCommentsQuery;
|
|
@@ -349,7 +354,8 @@ class ClassPage {
|
|
|
}
|
|
|
|
|
|
for(const property of properties) {
|
|
|
- const propertyItem = DOM.create({ tag: DOM.Tags.Div, cls: 'property-item', attr: { [ClassPage.Attributes.DataPropertyName]: property.key, [ClassPage.Attributes.DataPropertyType]: property.type }}, propertiesList).on(DOM.Events.MouseDown, (e) => {
|
|
|
+ const key = isStatics ? `${ClassPage.__static__}${property.key}` : property.key;
|
|
|
+ const propertyItem = DOM.create({ tag: DOM.Tags.Div, cls: 'property-item', attr: { [ClassPage.Attributes.DataPropertyName]: key, [ClassPage.Attributes.DataPropertyType]: property.type }}, propertiesList).on(DOM.Events.MouseDown, (e) => {
|
|
|
const element = CDElement.get(e.target);
|
|
|
|
|
|
if(e.buttons === DOM.MouseButtons.Right) {
|
|
@@ -362,9 +368,9 @@ class ClassPage {
|
|
|
if(propertyItemClickable(element))
|
|
|
return;
|
|
|
if(type === ClassPage.PropertyType.Inherited) {
|
|
|
- Url.goTo(`/class/${property.nearestParent}#${isMethods ? 'Methods' : 'Properties'}:${property.key}`);
|
|
|
+ Url.goTo(`/class/${property.nearestParent}#${isMethods ? 'Methods' : 'Properties'}:${key}`);
|
|
|
} else {
|
|
|
- this.searchPropertyInEditor(isMethods, property.dynamic, property.key);
|
|
|
+ this.searchPropertyInEditor(isMethods, property.dynamic, key);
|
|
|
}
|
|
|
}
|
|
|
});
|
|
@@ -401,7 +407,7 @@ class ClassPage {
|
|
|
const itemCommentText = DOM.create({ tag: DOM.Tags.Div, innerHTML: 'Comment:' });
|
|
|
const itemCommentCn = [itemCommentText];
|
|
|
|
|
|
- const loadedComment = Comments[type === ClassPage.PropertyType.Statics ? `__static__${property.key}` : property.key];
|
|
|
+ const loadedComment = Comments[type === ClassPage.PropertyType.Statics ? `${ClassPage.__static__}${property.key}` : property.key];
|
|
|
const loadedCommentText = loadedComment && typeof loadedComment === 'object' ? loadedComment.text : '';
|
|
|
|
|
|
const hasComment = loadedComment && typeof loadedComment === 'object' && loadedCommentText.length > 0;
|
|
@@ -413,7 +419,7 @@ class ClassPage {
|
|
|
propertyItem.setAttribute(ClassPage.Attributes.DataPropertyInherited, 'true');
|
|
|
}
|
|
|
|
|
|
- this.propertyItemElements[type === ClassPage.PropertyType.Statics ? `__static__${property.key}` : property.key] = propertyItem;
|
|
|
+ this.propertyItemElements[type === ClassPage.PropertyType.Statics ? `${ClassPage.__static__}${property.key}` : property.key] = propertyItem;
|
|
|
|
|
|
if(isEditor) {
|
|
|
const itemCommentInput = DOM.create({ tag: DOM.Tags.Textarea, cls: 'property-item-comment-input hidden', attr: { 'placeholder': 'Not commented yet...'} }).setValue(CDUtils.br2nl(loadedCommentText));
|
|
@@ -436,7 +442,7 @@ class ClassPage {
|
|
|
if(commentContent === CDUtils.br2nl(itemCommentStatic.getValue()) || commentContent === '' && itemCommentStatic.hasClass('empty'))
|
|
|
return;
|
|
|
|
|
|
- const propertyName = `${type === ClassPage.PropertyType.Statics ? '__static__' : ''}${property.key}`;
|
|
|
+ const propertyName = `${type === ClassPage.PropertyType.Statics ? ClassPage.__static__ : ''}${property.key}`;
|
|
|
const className = Class[ClassPage.ClassProperties.Name];
|
|
|
const classRoot = Class[ClassPage.ClassProperties.Root];
|
|
|
|
|
@@ -623,13 +629,15 @@ class ClassPage {
|
|
|
}
|
|
|
|
|
|
markContentInEditor() {
|
|
|
+ const staticsRange = this.getStaticsRange();
|
|
|
+
|
|
|
this.codeMirrorEditor.cmEachLine((lineHandle) => {
|
|
|
this.markExtend(lineHandle);
|
|
|
this.markMixins(lineHandle);
|
|
|
this.markZ8Locales(lineHandle);
|
|
|
this.markNew(lineHandle);
|
|
|
this.markThis(lineHandle);
|
|
|
- this.markProperties(lineHandle);
|
|
|
+ this.markProperties(lineHandle, staticsRange);
|
|
|
});
|
|
|
}
|
|
|
|
|
@@ -793,24 +801,30 @@ class ClassPage {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- markProperties(lineHandle) {
|
|
|
+ markProperties(lineHandle, staticsRange) {
|
|
|
const editor = this.codeMirrorEditor;
|
|
|
const text = lineHandle.text;
|
|
|
+ const lineNo = lineHandle.lineNo();
|
|
|
const regexp = /\t([\w]+):/g;
|
|
|
+
|
|
|
+ const isStatic = lineNo >= staticsRange.from && lineNo <= staticsRange.to;
|
|
|
+
|
|
|
let match;
|
|
|
while ((match = regexp.exec(text)) !== null) {
|
|
|
- const propertyName = match[1];
|
|
|
- const from = { line: lineHandle.lineNo(), ch: match.index + 1 };
|
|
|
- const to = { line: lineHandle.lineNo(), ch: match.index + match[0].length - 1 };
|
|
|
+ const propertyName = isStatic ? `${ClassPage.__static__}${match[1]}` : match[1];
|
|
|
+ const from = { line: lineNo, ch: match.index + 1 };
|
|
|
+ const to = { line: lineNo, ch: match.index + match[0].length - 1 };
|
|
|
|
|
|
const foundProperty = this.findClassProperty(propertyName);
|
|
|
|
|
|
if(!foundProperty)
|
|
|
continue;
|
|
|
-
|
|
|
+
|
|
|
+ const titlePropertyName = isStatic ? `${Class[ClassPage.ClassProperties.ShortName] || Class[ClassPage.ClassProperties.Name]}.${propertyName.replace(ClassPage.__static__, '')}` : propertyName;
|
|
|
+
|
|
|
editor.markText(from, to, {
|
|
|
className: 'cm-this-prop',
|
|
|
- title: `Ctrl+Click to go to ${foundProperty.type === 'method' ? 'method' : 'property'} '${propertyName}'`,
|
|
|
+ title: `Ctrl+Click to go to ${foundProperty.type === 'method' ? 'method' : 'property'} '${titlePropertyName}'`,
|
|
|
attributes: {
|
|
|
[ClassPage.Attributes.DataPropertyName]: propertyName,
|
|
|
[ClassPage.Attributes.DataPropertyType]: foundProperty.type === 'method' ? 'Methods' : 'Properties',
|
|
@@ -821,20 +835,63 @@ class ClassPage {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ getStaticsRange() {
|
|
|
+ const range = { from: -1, to: -1 };
|
|
|
+ let staticsParenthesisFlag = -1;
|
|
|
+ let found = false;
|
|
|
+
|
|
|
+ this.codeMirrorEditor.cmEachLine((lineHandle) => {
|
|
|
+ if(found)
|
|
|
+ return;
|
|
|
+
|
|
|
+ const text = lineHandle.text;
|
|
|
+ let ignoreFirstParenthesis = false;
|
|
|
+
|
|
|
+ if(staticsParenthesisFlag === -1 && text.match(/statics:\s*\{/)) {
|
|
|
+ staticsParenthesisFlag = 1;
|
|
|
+ ignoreFirstParenthesis = true;
|
|
|
+ range.from = lineHandle.lineNo();
|
|
|
+ }
|
|
|
+
|
|
|
+ if(staticsParenthesisFlag > 0) {
|
|
|
+ for(let i = 0; i < text.length; i++) {
|
|
|
+ if(text.charAt(i) === '{' && ignoreFirstParenthesis)
|
|
|
+ ignoreFirstParenthesis = false;
|
|
|
+ else if (text.charAt(i) === '{')
|
|
|
+ staticsParenthesisFlag++;
|
|
|
+ else if(text.charAt(i) === '}')
|
|
|
+ staticsParenthesisFlag--;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(staticsParenthesisFlag === 0) {
|
|
|
+ range.to = lineHandle.lineNo();
|
|
|
+ found = true;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ return range;
|
|
|
+ }
|
|
|
+
|
|
|
shortNameExists(shortName) {
|
|
|
return Object.keys(ClassList).map((key) => ClassList[key]).filter((item) => item[ClassPage.ClassProperties.ShortName] === shortName).length > 0;
|
|
|
}
|
|
|
|
|
|
findClassProperty(propertyName) {
|
|
|
+ if(propertyName.startsWith(ClassPage.__static__)) {
|
|
|
+ propertyName = propertyName.slice(10);
|
|
|
+ const statics = Class[ClassPage.ClassProperties.Statics];
|
|
|
+ const foundStatic = statics.filter((prop) => prop.key === propertyName)[0];
|
|
|
+ return foundStatic;
|
|
|
+ }
|
|
|
+
|
|
|
const dynamicProperties = Class[ClassPage.ClassProperties.DynamicProperties];
|
|
|
const properties = Class[ClassPage.ClassProperties.Properties];
|
|
|
- const statics = Class[ClassPage.ClassProperties.Statics];
|
|
|
|
|
|
- const foundStatic = statics.filter((prop) => prop.key === propertyName)[0];
|
|
|
const foundDynamic = dynamicProperties.filter((prop) => prop.key === propertyName)[0];
|
|
|
const foundProperty = properties.filter((prop) => prop.key === propertyName)[0];
|
|
|
|
|
|
- return foundStatic || foundDynamic || foundProperty;
|
|
|
+ return foundDynamic || foundProperty;
|
|
|
}
|
|
|
|
|
|
onClassLinkClick(fragment) {
|
|
@@ -871,7 +928,7 @@ class ClassPage {
|
|
|
}
|
|
|
|
|
|
onClassClick(e) {
|
|
|
- let element = CDElement.get(e.target);
|
|
|
+ let element = CDElement.get(e.target);
|
|
|
while(!element.hasClass(ClassPage.StyleClasses.ClassItem))
|
|
|
element = element.getParent();
|
|
|
Url.goTo(`/class/${element.getAttribute(ClassPage.Attributes.DataClassName)}`);
|
|
@@ -885,28 +942,42 @@ class ClassPage {
|
|
|
(mode === ClassPage.Mode.Tabs ? this.listModeButton : this.tabsModeButton).removeClass(ClassPage.StyleClasses.Selected);
|
|
|
}
|
|
|
|
|
|
- searchInEditor(...queries) {
|
|
|
+ searchInEditor(isStatic, ...queries) {
|
|
|
+ this.switchFullSource(true);
|
|
|
+
|
|
|
const editor = this.codeMirrorEditor;
|
|
|
+ const staticsRange = this.getStaticsRange();
|
|
|
+ const staticsStart = staticsRange.from;
|
|
|
+ const staticsEnd = staticsRange.to;
|
|
|
+
|
|
|
for(const query of queries) {
|
|
|
const cursor = editor.getSearchCursor(query, CodeMirror.Pos(editor.cmFirstLine(), 0), { caseFold: false, multiline: true });
|
|
|
- if(cursor.find(false)) {
|
|
|
- this.switchFullSource(true);
|
|
|
- this.openTab('Editor');
|
|
|
- editor.setSelection(cursor.from(), cursor.to());
|
|
|
- editor.scrollIntoView({from: cursor.from(), to: cursor.to()}, 100);
|
|
|
- return;
|
|
|
+ while(cursor.find()) {
|
|
|
+ const from = cursor.from();
|
|
|
+ const to = cursor.to();
|
|
|
+ const lineIndex = from.line;
|
|
|
+
|
|
|
+ if((isStatic && lineIndex >= staticsStart && lineIndex <= staticsEnd) || (!isStatic && (lineIndex < staticsStart || lineIndex > staticsEnd))) {
|
|
|
+ this.openTab('Editor');
|
|
|
+ editor.setSelection(from, to);
|
|
|
+ editor.scrollIntoView({ from: from, to: to }, 100);
|
|
|
+ return;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
searchPropertyInEditor(isMethod, isDynamic, propertyName) {
|
|
|
+ const isStatic = propertyName.startsWith(ClassPage.__static__);
|
|
|
+ propertyName = isStatic ? propertyName.slice(10) : propertyName;
|
|
|
+
|
|
|
if(isMethod) {
|
|
|
- this.searchInEditor(`${propertyName}: function`);
|
|
|
+ this.searchInEditor(isStatic, `${propertyName}: function`);
|
|
|
} else {
|
|
|
if(isDynamic)
|
|
|
- this.searchInEditor(`this.${propertyName} =`, `this.${propertyName}`);
|
|
|
+ this.searchInEditor(false, `this.${propertyName} =`, `this.${propertyName}`);
|
|
|
else
|
|
|
- this.searchInEditor(`${propertyName}: `);
|
|
|
+ this.searchInEditor(isStatic, `${propertyName}: `);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1085,6 +1156,15 @@ class ClassPage {
|
|
|
this.createContextMenuItem('CopyLink', 'Copy link', () => {
|
|
|
DOM.copyToClipboard(`${Url.getFullPath()}#${propertyItemType === 'method' ? 'Methods' : 'Properties'}:${propertyItemName}`);
|
|
|
});
|
|
|
+ this.createContextMenuDelimiter();
|
|
|
+ this.createContextMenuItem('CopyHtmlLink', 'Copy HTML link', () => {
|
|
|
+ let linkText = propertyItemName;
|
|
|
+ if(propertyItemName.startsWith(ClassPage.__static__))
|
|
|
+ linkText = `${Class[ClassPage.ClassProperties.ShortName] || Class[ClassPage.ClassProperties.Name]}.${propertyItemName.replace(ClassPage.__static__, '')}`;
|
|
|
+ if(propertyItemType === 'method')
|
|
|
+ linkText = `${linkText}()`;
|
|
|
+ DOM.copyToClipboard(`<a href="${Url.getPath()}#${propertyItemType === 'method' ? 'Methods' : 'Properties'}:${propertyItemName}">${linkText}</a>`);
|
|
|
+ });
|
|
|
break;
|
|
|
}
|
|
|
|