api-console-assets
Version:
This repo only exists to publish api console components to npm
421 lines (391 loc) • 12.5 kB
HTML
<!--
@license
Copyright 2016 The Advanced REST client authors <arc@mulesoft.com>
Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.
-->
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../raml-behaviors/raml-behavior.html">
<link rel="import" href="../raml-aware/raml-aware.html">
<!--
The `<raml-path-to-object>` is a convenient way of getting information about
currently selected path.
Selected path is a result of `raml-path-selector` element.
The element will give additional information about the path:
- what type of data it represents (type, documentation, resource, method, summary)
- the object pointed by the path
- in case of resources / methods - parent resource (if available).
The element will assign information listed above to it's properties so you can
listen for changes directly on the element. However, the element will fire a
custom event when any property change. See events list for more details.
If the `auto` property is set then it will set a listeners for the
`raml-selected-path-changed` event and fire back one of the events supported by
this element as descrived below in the event section.
### Usage
```html
<raml-path-selector></raml-path-selector>
<raml-path-to-object auto></raml-path-to-object>
<script>
// You can construct path manually, but there's an element for that!
var selector = document.querySelector('raml-path-selector');
var object = document.querySelector('raml-path-to-object');
// Sets the (enhanced) RAML object on the element
// See https://elements.advancedrestclient.com/elements/raml-json-enhance
window.addEventListener('raml-json-enhance-ready', function(e) {
selector.raml = e.detail.json;
object.raml = e.detail.json;
});
// Fired when the object for the path is computed.
// Though, it's a synchronous operation so the `selectedObject` can be read
// from the `object` element right after assigning the path value.
window.addEventListener('raml-selected-object-changed', function(e) {
var selectedObject = e.detail.selectedObject;
// Assign to request or documentation panel.
});
// This event's boubbles so it's safe to listen on `window` object.
window.addEventListener('raml-is-resource-changed', function(e) {
var isResource = e.detail.state;
// if true then selected object is a resource.
});
</script>
```
In the Polymer powered application:
```
<raml-path-selector raml="[[raml]]" selected-path="{{selectedPath}}"></raml-path-selector>
<raml-path-to-object
selected-path="{{selectedPath}}"
selected-object="{{selectedObject}}"
is-method="{{isMethod}}"
is-resource="{{isResource}}"
is-documentation="{{isDocumentation}}"
is-type="{{isType}}"
is-summary="{{isSummary}}"></raml-path-to-object>
```
@group RAML Elements
@element raml-path-to-object
@demo demo/index.html
@hero hero.svg
-->
<dom-module id="raml-path-to-object">
<template>
<style>
:host {
display: none;
}
</style>
<template is="dom-if" if="[[aware]]" restamp="true">
<raml-aware raml="{{raml}}" scope="[[aware]]"></raml-aware>
</template>
</template>
<script>
Polymer({
is: 'raml-path-to-object',
behaviors: [Polymer.RamlBehavior],
/**
* Fired when selected object is a method description
*
* @event raml-is-method-changed
* @param {Boolean} state `true` if selected object is a method and `false`
* otherwise
*/
/**
* Fired when selected object is a resource description.
*
* @event raml-is-resource-changed
* @param {Boolean} state `true` if selected object is a resource and
* `false` otherwise
*/
/**
* Fired when selected object is a documentation description
*
* @event raml-is-documentation-changed
* @param {Boolean} state `true` if selected object is a documentation and
* `false` otherwise
*/
/**
* Fired when selected object is a summary.
*
* @event raml-is-summary-changed
* @param {Boolean} state `true` if selected object is a summary and
* `false` otherwise
*/
/**
* Fired when selected object is a type description.
*
* @event raml-is-type-changed
* @param {Boolean} state `true` if selected object is a type and `false`
* otherwise
*/
/**
* Fired when the object from the path has been computed.
*
* @event raml-selected-object-changed
* @param {Object} selectedObject The object on which the path points to.
*/
/**
* Fired when computed value for the parent of the selected object changed.
* This can change only for the resources and methods.
*
* @event raml-selected-parent-changed
* @param {Boolean} selectedParent Computed parent object of the
* `selectedObject`.
*/
properties: {
// Currently selected path by the path selector (or anhy other)
selectedPath: String,
// An object read from path.
selectedObject: {
type: Object,
notify: true,
readOnly: true
},
// Parent of the selected object (if any is possible)
selectedParent: {
type: Object,
notify: true,
readOnly: true
},
// True if the selected object is a method definition
isMethod: {
type: Boolean,
value: false,
notify: true,
readOnly: true
},
// True if the selected object is a resource definition
isResource: {
type: Boolean,
value: false,
notify: true,
readOnly: true
},
// True if the selected object is a documentation definition
isDocumentation: {
type: Boolean,
value: false,
notify: true,
readOnly: true
},
// True if the selected object is a summary of the api
isSummary: {
type: Boolean,
readOnly: true,
notify: true,
value: false
},
// True if the selected object is a type definition
isType: {
type: Boolean,
readOnly: true,
notify: true,
value: false
},
// Name of the `<raml-aware>` scope, so it will fill the raml property.
aware: String,
// If true, then it will listen for change events instead using data binding
auto: {
type: Boolean,
value: false,
observer: '_autoChanged'
}
},
observers: [
'_ramlChanged(raml.*)',
'_pathChanged(selectedPath, raml)',
'_fireSelectedObject(selectedObject.*)',
'_fireSelectedParent(selectedParent.*)',
'_fireIsMethodState(isMethod)',
'_fireIsResourceState(isResource)',
'_fireIsDocumentationState(isDocumentation)',
'_fireIsSummaryState(isSummary)',
'_fireIsTypeState(isType)'
],
attached: function() {
this._eventTarget = Polymer.dom(this).host || document;
this._autoChanged(this.auto);
},
_autoChanged: function(state) {
if (state) {
this._attacheListeners();
} else {
this._detachListeners();
}
},
_attacheListeners: function() {
if (!this._eventTarget) {
return;
}
this._detachListeners();
this.listen(this._eventTarget, 'raml-selected-path-changed',
'_pathChangeHandler');
},
_detachListeners: function() {
if (!this._eventTarget) {
return;
}
this.unlisten(this._eventTarget, 'raml-selected-path-changed',
'_pathChangeHandler');
},
_pathChangeHandler: function(e, detail) {
this.set('selectedPath', detail.path);
},
// Restore properties to the original state
clear: function() {
this._setSelectedObject(undefined);
this._setIsMethod(false);
this._setIsResource(false);
this._setIsDocumentation(false);
this._setIsSummary(false);
this._setIsType(false);
this._cachedRegexps = {};
},
// Handler for the raml change. Resets the data.
_ramlChanged: function() {
this.clear();
},
// Called when path changes and raml is set.
_pathChanged: function(path, raml) {
if (!raml || !path) {
return this.clear();
}
this._analysePath(path);
var obj = this._computeObject(path);
if (!obj) {
return this.clear();
}
this._setSelectedObject(obj);
this._selectParent(path);
},
_analysePath: function(path) {
var _path;
if (path.indexOf('.') !== -1) {
var parts = path.split('.');
parts.pop(); // Last array index
_path = parts.pop();
} else {
_path = path;
}
var method = false;
var doc = false;
var resource = false;
var type = false;
var summary = false;
switch (_path) {
case 'resources':
resource = true;
break;
case 'methods':
method = true;
break;
case 'documentation':
doc = true;
break;
case 'types':
type = true;
break;
case 'summary':
summary = true;
break;
default:
return this.clear();
}
this._setIsMethod(method);
this._setIsResource(resource);
this._setIsDocumentation(doc);
this._setIsSummary(summary);
this._setIsType(type);
},
_selectParent: function(path) {
if (!(this.isMethod || this.isResource || this.isSummary || this.isType)) {
// No parent.
return this._setSelectedParent(undefined);
}
var parts = path.split('.');
parts.splice(parts.length - 2, 2);
var parentPath = parts.join('.');
if (!parentPath) {
return this._setSelectedParent(undefined);
}
var obj = this.get('raml.' + parentPath);
if (!obj) {
return this._setSelectedParent(undefined);
}
this._setSelectedParent(obj);
},
/**
* Inserts dependencies definitions to current node.
* It will update query parameters, uri parameters, security schemas etc with it's definitions.
*
* As a result, instead of array of ID's in the `is` property, full definition of trait will
* be inserted. `uriParameters` will be added as a `uriParameters` property. Ans so on.
*
* This function must be called after type of object has been determined.
* @param {String} path A path to the object.
*/
_computeObject: function(path) {
if (this.isDocumentation) {
// No dependencies here
return this.get('raml.' + path);
}
if (this.isSummary) {
return this.raml;
}
if (this.isType) {
var names = Object.getOwnPropertyNames(this.raml.types);
var match = path.match(/(\d+)/);
var index = Number(match[1]);
try {
return this.raml.types[names[index]];
} catch (e) {
console.error('Unknown type in types list', names[index]);
}
return;
}
var current = this.get('raml.' + path);
return current;
},
_fireSelectedObject: function() {
this.fire('raml-selected-object-changed', {
selectedObject: this.selectedObject
});
},
_fireSelectedParent: function() {
this.fire('raml-selected-parent-changed', {
selectedParent: this.selectedParent
});
},
_fireIsMethodState: function(isMethod) {
this.fire('raml-is-method-changed', {
state: isMethod
});
},
_fireIsResourceState: function(isResource) {
this.fire('raml-is-resource-changed', {
state: isResource
});
},
_fireIsDocumentationState: function(isDocumentation) {
this.fire('raml-is-documentation-changed', {
state: isDocumentation
});
},
_fireIsSummaryState: function(isSummary) {
this.fire('raml-is-summary-changed', {
state: isSummary
});
},
_fireIsTypeState: function(isType) {
this.fire('raml-is-type-changed', {
state: isType
});
}
});
</script>
</dom-module>