Bläddra i källkod

Refactor: move dom utils to @grafana/ui (#17976)

Ryan McKinley 6 år sedan
förälder
incheckning
ccc3d88cee

+ 4 - 4
public/app/features/explore/utils/dom.ts → packages/grafana-ui/src/utils/dom.ts

@@ -1,6 +1,6 @@
 // Node.closest() polyfill
 if ('Element' in window && !Element.prototype.closest) {
-  Element.prototype.closest = function(this: any, s) {
+  Element.prototype.closest = function(this: any, s: string) {
     const matches = (this.document || this.ownerDocument).querySelectorAll(s);
     let el = this;
     let i;
@@ -15,7 +15,7 @@ if ('Element' in window && !Element.prototype.closest) {
   };
 }
 
-export function getPreviousCousin(node, selector) {
+export function getPreviousCousin(node: any, selector: string) {
   let sibling = node.parentElement.previousSibling;
   let el;
   while (sibling) {
@@ -30,12 +30,12 @@ export function getPreviousCousin(node, selector) {
 
 export function getNextCharacter(global = window) {
   const selection = global.getSelection();
-  if (!selection.anchorNode) {
+  if (!selection || !selection.anchorNode) {
     return null;
   }
 
   const range = selection.getRangeAt(0);
   const text = selection.anchorNode.textContent;
   const offset = range.startOffset;
-  return text.substr(offset, 1);
+  return text!.substr(offset, 1);
 }

+ 4 - 0
packages/grafana-ui/src/utils/index.ts

@@ -7,3 +7,7 @@ export * from './deprecationWarning';
 export * from './validate';
 export { getFlotPairs } from './flotPairs';
 export * from './slate';
+
+// Export with a namespace
+import * as DOMUtil from './dom'; // includes Element.closest polyfil
+export { DOMUtil };

+ 2 - 2
public/app/plugins/datasource/grafana-azure-monitor-datasource/editor/KustoQueryField.tsx

@@ -4,7 +4,7 @@ import Plain from 'slate-plain-serializer';
 
 import QueryField from './query_field';
 import debounce from 'lodash/debounce';
-import { getNextCharacter } from 'app/features/explore/utils/dom';
+import { DOMUtil } from '@grafana/ui';
 
 import { KEYWORDS, functionTokens, operatorTokens, grafanaMacros } from './kusto/kusto';
 // import '../sass/editor.base.scss';
@@ -203,7 +203,7 @@ export default class KustoQueryField extends QueryField {
 
     // Modify suggestion based on context
 
-    const nextChar = getNextCharacter();
+    const nextChar = DOMUtil.getNextCharacter();
     if (suggestion.type === 'function') {
       if (!nextChar || nextChar !== '(') {
         suggestionText += '(';

+ 5 - 6
public/app/plugins/datasource/loki/components/LokiQueryFieldForm.tsx

@@ -10,13 +10,12 @@ import QueryField, { TypeaheadInput, QueryFieldState } from 'app/features/explor
 
 // Utils & Services
 // dom also includes Element polyfills
-import { getNextCharacter, getPreviousCousin } from 'app/features/explore/utils/dom';
 import BracesPlugin from 'app/features/explore/slate-plugins/braces';
 
 // Types
 import { LokiQuery } from '../types';
 import { TypeaheadOutput, HistoryItem } from 'app/types/explore';
-import { DataSourceApi, ExploreQueryFieldProps, DataSourceStatus } from '@grafana/ui';
+import { DataSourceApi, ExploreQueryFieldProps, DataSourceStatus, DOMUtil } from '@grafana/ui';
 import { AbsoluteTimeRange } from '@grafana/data';
 
 function getChooserText(hasSyntax: boolean, hasLogLabels: boolean, datasourceStatus: DataSourceStatus) {
@@ -36,7 +35,7 @@ function willApplySuggestion(suggestion: string, { typeaheadContext, typeaheadTe
   // Modify suggestion based on context
   switch (typeaheadContext) {
     case 'context-labels': {
-      const nextChar = getNextCharacter();
+      const nextChar = DOMUtil.getNextCharacter();
       if (!nextChar || nextChar === '}' || nextChar === ',') {
         suggestion += '=';
       }
@@ -48,7 +47,7 @@ function willApplySuggestion(suggestion: string, { typeaheadContext, typeaheadTe
       if (!typeaheadText.match(/^(!?=~?"|")/)) {
         suggestion = `"${suggestion}`;
       }
-      if (getNextCharacter() !== '"') {
+      if (DOMUtil.getNextCharacter() !== '"') {
         suggestion = `${suggestion}"`;
       }
       break;
@@ -130,9 +129,9 @@ export class LokiQueryFieldForm extends React.PureComponent<LokiQueryFieldFormPr
 
     // Get DOM-dependent context
     const wrapperClasses = Array.from(wrapperNode.classList);
-    const labelKeyNode = getPreviousCousin(wrapperNode, '.attr-name');
+    const labelKeyNode = DOMUtil.getPreviousCousin(wrapperNode, '.attr-name');
     const labelKey = labelKeyNode && labelKeyNode.textContent;
-    const nextChar = getNextCharacter();
+    const nextChar = DOMUtil.getNextCharacter();
 
     const result = datasource.languageProvider.provideCompletionItems(
       { text, value, prefix, wrapperClasses, labelKey },

+ 5 - 6
public/app/plugins/datasource/prometheus/components/PromQueryField.tsx

@@ -10,12 +10,11 @@ import Prism from 'prismjs';
 import { TypeaheadOutput, HistoryItem } from 'app/types/explore';
 
 // dom also includes Element polyfills
-import { getNextCharacter, getPreviousCousin } from 'app/features/explore/utils/dom';
 import BracesPlugin from 'app/features/explore/slate-plugins/braces';
 import QueryField, { TypeaheadInput, QueryFieldState } from 'app/features/explore/QueryField';
 import { PromQuery, PromContext, PromOptions } from '../types';
 import { CancelablePromise, makePromiseCancelable } from 'app/core/utils/CancelablePromise';
-import { ExploreQueryFieldProps, DataSourceStatus, QueryHint } from '@grafana/ui';
+import { ExploreQueryFieldProps, DataSourceStatus, QueryHint, DOMUtil } from '@grafana/ui';
 import { isDataFrame, toLegacyResponseData } from '@grafana/data';
 import { PrometheusDatasource } from '../datasource';
 
@@ -73,7 +72,7 @@ export function willApplySuggestion(suggestion: string, { typeaheadContext, type
   // Modify suggestion based on context
   switch (typeaheadContext) {
     case 'context-labels': {
-      const nextChar = getNextCharacter();
+      const nextChar = DOMUtil.getNextCharacter();
       if (!nextChar || nextChar === '}' || nextChar === ',') {
         suggestion += '=';
       }
@@ -85,7 +84,7 @@ export function willApplySuggestion(suggestion: string, { typeaheadContext, type
       if (!typeaheadText.match(/^(!?=~?"|")/)) {
         suggestion = `"${suggestion}`;
       }
-      if (getNextCharacter() !== '"') {
+      if (DOMUtil.getNextCharacter() !== '"') {
         suggestion = `${suggestion}"`;
       }
       break;
@@ -282,9 +281,9 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
 
     // Get DOM-dependent context
     const wrapperClasses = Array.from(wrapperNode.classList);
-    const labelKeyNode = getPreviousCousin(wrapperNode, '.attr-name');
+    const labelKeyNode = DOMUtil.getPreviousCousin(wrapperNode, '.attr-name');
     const labelKey = labelKeyNode && labelKeyNode.textContent;
-    const nextChar = getNextCharacter();
+    const nextChar = DOMUtil.getNextCharacter();
 
     const result = this.languageProvider.provideCompletionItems(
       { text, value, prefix, wrapperClasses, labelKey },