mirror of
https://github.com/dataarts/dat.gui.git
synced 2024-12-12 04:08:27 +00:00
7125 lines
233 KiB
HTML
7125 lines
233 KiB
HTML
|
<!--
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
-->
|
||
|
|
||
|
<style>
|
||
|
|
||
|
body {
|
||
|
margin: 0;
|
||
|
}
|
||
|
|
||
|
</style>
|
||
|
|
||
|
<div hidden><!--
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
-->
|
||
|
|
||
|
<!--
|
||
|
The `core-layout` element is a helper for using
|
||
|
[CSS3 Flexible Boxes](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes).
|
||
|
A `core-layout` element enables a set of css selectors for easy flexbox styling.
|
||
|
|
||
|
Example:
|
||
|
|
||
|
<core-layout>
|
||
|
<div>Left</div>
|
||
|
<div core-flex>Main</div>
|
||
|
<div>Right</div>
|
||
|
</core-layout>
|
||
|
|
||
|
Renders something like this:
|
||
|
|
||
|
---------------------------------
|
||
|
|-------------------------------|
|
||
|
||Left| Main |Right||
|
||
|
|-------------------------------|
|
||
|
---------------------------------
|
||
|
|
||
|
__Note__: the `core-layout` element applies layout to itself if it has children or to
|
||
|
its parent element, if it does not. This feature allows you to apply layout to an
|
||
|
arbitrary parent.
|
||
|
|
||
|
Elements can layout horizontally, such that their items stack
|
||
|
left to right or vertically, such that their items stack top to bottom. The
|
||
|
default is horizontal. Set `vertical` to true to layout the elements vertically.
|
||
|
|
||
|
To make a particular child _flexible_, use the `core-flex` attribute.
|
||
|
You can control flexibility from 1 to 3 by giving the attribute a
|
||
|
corresponding value. For other values, apply the css manually.
|
||
|
|
||
|
It's common in flexbox parlance to hear the terms _main axis_ and _cross axis_.
|
||
|
For a horizontal layout the main axis is horizontal and the cross axis is vertical.
|
||
|
These are exchanged for a vertical layout.
|
||
|
|
||
|
To effect alignment in the main axis, use the `justify` attribute. The
|
||
|
supported values are `start`, `center`, `end`, and `between`.
|
||
|
|
||
|
To effect alignment in the cross axis, use the `align` attribute. The
|
||
|
supported values are `start`, `center`, and `end`.
|
||
|
|
||
|
Note, it's also possible to include the `core-layout.css` stylesheet separate
|
||
|
from the `core-layout` element. Including the element automatically includes
|
||
|
the stylesheet. To use the stylesheet independent of the element, css classes
|
||
|
should be used of the following form: `core-h`, `core-v`, `core-flex`,
|
||
|
`core-justify-start`, and `core-align-start`.
|
||
|
|
||
|
The `core-layout` and css file also provide a few commonly needed layout
|
||
|
behaviors. Apply the `core-fit` class to fit an element to its container. To
|
||
|
ensure a container will contain an element inside it with the `core-fit` class
|
||
|
give it the `core-relative` class.
|
||
|
|
||
|
More examples:
|
||
|
|
||
|
<core-layout vertical>
|
||
|
|
||
|
<div>Header</div>
|
||
|
<div core-flex>Body</div>
|
||
|
<div>Footer</div>
|
||
|
|
||
|
</core-layout>
|
||
|
|
||
|
----------
|
||
|
||------||
|
||
|
||Header||
|
||
|
||------||
|
||
|
||Body ||
|
||
|
|| ||
|
||
|
|| ||
|
||
|
|| ||
|
||
|
|| ||
|
||
|
|| ||
|
||
|
|| ||
|
||
|
||------||
|
||
|
||Footer||
|
||
|
||------||
|
||
|
----------
|
||
|
|
||
|
Justify:
|
||
|
|
||
|
<core-layout justify="end">
|
||
|
<div core-flex>Left</div>
|
||
|
<div>Main</div>
|
||
|
<div>Right</div>
|
||
|
</core-layout>
|
||
|
|
||
|
---------------------------------
|
||
|
|-------------------------------|
|
||
|
|| Left|Main|Right||
|
||
|
|-------------------------------|
|
||
|
---------------------------------
|
||
|
|
||
|
Align:
|
||
|
|
||
|
<core-layout align="center">
|
||
|
<div>Left</div>
|
||
|
<div core-flex>Main</div>
|
||
|
<div>Right</div>
|
||
|
</core-layout>
|
||
|
|
||
|
---------------------------------
|
||
|
|-------------------------------|
|
||
|
|| | | ||
|
||
|
||Left| Main |Right||
|
||
|
|| | | ||
|
||
|
|-------------------------------|
|
||
|
---------------------------------
|
||
|
|
||
|
|
||
|
To layout contents of a parent element, place a `core-layout` inside of it:
|
||
|
|
||
|
<some-element>
|
||
|
<core-layout></core-layout>
|
||
|
<div>Left</div>
|
||
|
<div core-flex>Main</div>
|
||
|
<div>Right</div>
|
||
|
<some-element>
|
||
|
|
||
|
---------------------------------
|
||
|
|-------------------------------|
|
||
|
||Left| Main |Right||
|
||
|
|-------------------------------|
|
||
|
---------------------------------
|
||
|
|
||
|
You may also use the `core-layout` stylesheet directly:
|
||
|
|
||
|
<link rel="stylesheet" href="../core-layout/core-layout.css">
|
||
|
<div class="core-h core-justify-end">
|
||
|
<div core-flex>Left</div>
|
||
|
<div>Main</div>
|
||
|
<div>Right</div>
|
||
|
</div>
|
||
|
|
||
|
---------------------------------
|
||
|
|-------------------------------|
|
||
|
|| Left|Main|Right||
|
||
|
|-------------------------------|
|
||
|
---------------------------------
|
||
|
|
||
|
@group Polymer Core Elements
|
||
|
@element core-layout
|
||
|
|
||
|
-->
|
||
|
<link rel="import" href="../polymer/polymer.html">
|
||
|
|
||
|
<polymer-element name="core-layout" attributes="vertical justify align isContainer reverse" assetpath="../core-layout/">
|
||
|
|
||
|
<template>
|
||
|
|
||
|
<style no-shim="">/*
|
||
|
Copyright 2013 The Polymer Authors. All rights reserved.
|
||
|
Use of this source code is governed by a BSD-style
|
||
|
license that can be found in the LICENSE file.
|
||
|
*/
|
||
|
|
||
|
.core-h, .core-v {
|
||
|
display: -webkit-box !important;
|
||
|
display: -ms-flexbox !important;
|
||
|
display: -moz-flex !important;
|
||
|
display: -webkit-flex !important;
|
||
|
display: flex !important;
|
||
|
}
|
||
|
|
||
|
.core-h {
|
||
|
-webkit-box-orient: horizontal;
|
||
|
-ms-flex-direction: row;
|
||
|
-moz-flex-direction: row;
|
||
|
-webkit-flex-direction: row;
|
||
|
flex-direction: row;
|
||
|
}
|
||
|
|
||
|
.core-h.core-reverse {
|
||
|
-webkit-box-direction: reverse;
|
||
|
-ms-flex-direction: row-reverse;
|
||
|
-moz-flex-direction: row-reverse;
|
||
|
-webkit-flex-direction: row-reverse;
|
||
|
flex-direction: row-reverse;
|
||
|
}
|
||
|
|
||
|
.core-v {
|
||
|
-webkit-box-orient: vertical;
|
||
|
-ms-flex-direction: column;
|
||
|
-moz-flex-direction: column;
|
||
|
-webkit-flex-direction: column;
|
||
|
flex-direction: column;
|
||
|
}
|
||
|
|
||
|
.core-v.core-reverse {
|
||
|
-webkit-box-direction: reverse;
|
||
|
-ms-flex-direction: column-reverse;
|
||
|
-moz-flex-direction: column-reverse;
|
||
|
-webkit-flex-direction: column-reverse;
|
||
|
flex-direction: column-reverse;
|
||
|
}
|
||
|
|
||
|
.core-relative {
|
||
|
position: relative;
|
||
|
}
|
||
|
|
||
|
.core-fit {
|
||
|
position: absolute;
|
||
|
top: 0;
|
||
|
left: 0;
|
||
|
height: 100%;
|
||
|
width: 100%;
|
||
|
}
|
||
|
|
||
|
body.core-fit {
|
||
|
margin: 0;
|
||
|
}
|
||
|
|
||
|
.core-flex, [core-flex] {
|
||
|
-webkit-box-flex: 1;
|
||
|
-ms-flex: 1;
|
||
|
-moz-flex: 1;
|
||
|
-webkit-flex: 1;
|
||
|
flex: 1;
|
||
|
}
|
||
|
|
||
|
.core-flex-auto, [core-flex-auto] {
|
||
|
-webkit-box-flex: 1;
|
||
|
-ms-flex: 1 1 auto;
|
||
|
-moz-flex: 1 1 auto;
|
||
|
-webkit-flex: 1 1 auto;
|
||
|
flex: 1 1 auto;
|
||
|
}
|
||
|
|
||
|
.core-flex-none, [core-flex-none] {
|
||
|
-webkit-box-flex: none;
|
||
|
-ms-flex: none;
|
||
|
-moz-flex: none;
|
||
|
-webkit-flex: none;
|
||
|
flex: none;
|
||
|
}
|
||
|
|
||
|
.core-flex1, [core-flex=1] {
|
||
|
-webkit-box-flex: 1;
|
||
|
-ms-flex: 1;
|
||
|
-moz-flex: 1;
|
||
|
-webkit-flex: 1;
|
||
|
flex: 1;
|
||
|
}
|
||
|
|
||
|
.core-flex2, [core-flex=2] {
|
||
|
-webkit-box-flex: 2;
|
||
|
-ms-flex: 2;
|
||
|
-moz-flex: 2;
|
||
|
-webkit-flex: 2;
|
||
|
flex: 2;
|
||
|
}
|
||
|
|
||
|
.core-flex3, [core-flex=3] {
|
||
|
-webkit-box-flex: 3;
|
||
|
-ms-flex: 3;
|
||
|
-moz-flex: 3;
|
||
|
-webkit-flex: 3;
|
||
|
flex: 3;
|
||
|
}
|
||
|
|
||
|
/* distributed elements */
|
||
|
::content > .core-flex, ::content > [core-flex] {
|
||
|
-webkit-box-flex: 1;
|
||
|
-ms-flex: 1;
|
||
|
-moz-flex: 1;
|
||
|
-webkit-flex: 1;
|
||
|
flex: 1;
|
||
|
}
|
||
|
|
||
|
::content > .core-flex-auto, ::content > [core-flex-auto] {
|
||
|
-webkit-box-flex: 1;
|
||
|
-ms-flex: 1 1 auto;
|
||
|
-moz-flex: 1 1 auto;
|
||
|
-webkit-flex: 1 1 auto;
|
||
|
flex: 1 1 auto;
|
||
|
}
|
||
|
|
||
|
::content > .core-flex-none, ::content > [core-flex-none] {
|
||
|
-webkit-box-flex: none;
|
||
|
-ms-flex: none;
|
||
|
-moz-flex: none;
|
||
|
-webkit-flex: none;
|
||
|
flex: none;
|
||
|
}
|
||
|
|
||
|
::content > .core-flex1, ::content > [core-flex=1] {
|
||
|
-webkit-box-flex: 1;
|
||
|
-ms-flex: 1;
|
||
|
-moz-flex: 1;
|
||
|
-webkit-flex: 1;
|
||
|
flex: 1;
|
||
|
}
|
||
|
|
||
|
::content > .core-flex2, ::content > [core-flex=2] {
|
||
|
-webkit-box-flex: 2;
|
||
|
-ms-flex: 2;
|
||
|
-moz-flex: 2;
|
||
|
-webkit-flex: 2;
|
||
|
flex: 2;
|
||
|
}
|
||
|
|
||
|
::content > .core-flex3, ::content > [core-flex=3] {
|
||
|
-webkit-box-flex: 3;
|
||
|
-ms-flex: 3;
|
||
|
-moz-flex: 3;
|
||
|
-webkit-flex: 3;
|
||
|
flex: 3;
|
||
|
}
|
||
|
|
||
|
/* alignment in main axis */
|
||
|
.core-justify-start {
|
||
|
-webkit-box-pack: start;
|
||
|
-ms-flex-pack: start;
|
||
|
-moz-justify-content: flex-start;
|
||
|
-webkit-justify-content: flex-start;
|
||
|
justify-content: flex-start;
|
||
|
}
|
||
|
|
||
|
.core-justify-center {
|
||
|
-webkit-box-pack: center;
|
||
|
-ms-flex-pack: center;
|
||
|
-moz-justify-content: center;
|
||
|
-webkit-justify-content: center;
|
||
|
justify-content: center;
|
||
|
}
|
||
|
|
||
|
.core-justify-end {
|
||
|
-webkit-box-pack: end;
|
||
|
-ms-flex-pack: end;
|
||
|
-moz-justify-content: flex-end;
|
||
|
-webkit-justify-content: flex-end;
|
||
|
justify-content: flex-end;
|
||
|
}
|
||
|
|
||
|
.core-justify-between {
|
||
|
-webkit-box-pack: justify;
|
||
|
-ms-flex-pack: justify;
|
||
|
-moz-justify-content: space-between;
|
||
|
-webkit-justify-content: space-between;
|
||
|
justify-content: space-between;
|
||
|
}
|
||
|
|
||
|
/* alignment in cross axis */
|
||
|
.core-align-start {
|
||
|
-webkit-box-align: start;
|
||
|
-ms-flex-align: start;
|
||
|
-moz-align-items: flex-start;
|
||
|
-webkit-align-items: flex-start;
|
||
|
align-items: flex-start;
|
||
|
}
|
||
|
|
||
|
.core-align-center {
|
||
|
-webkit-box-align: center;
|
||
|
-ms-flex-align: center;
|
||
|
-moz-align-items: center;
|
||
|
-webkit-align-items: center;
|
||
|
align-items: center;
|
||
|
}
|
||
|
|
||
|
.core-align-end {
|
||
|
-webkit-box-align: end;
|
||
|
-ms-flex-align: end;
|
||
|
-moz-align-items: flex-end;
|
||
|
-webkit-align-items: flex-end;
|
||
|
align-items: flex-end;
|
||
|
}
|
||
|
</style>
|
||
|
<style no-shim="">/*
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
*/
|
||
|
|
||
|
:host {
|
||
|
display: -webkit-box !important;
|
||
|
display: -ms-flexbox !important;
|
||
|
display: -moz-flex !important;
|
||
|
display: -webkit-flex !important;
|
||
|
display: flex !important;
|
||
|
}
|
||
|
|
||
|
:host(.core-h) {
|
||
|
-webkit-box-orient: horizontal;
|
||
|
-ms-flex-direction: row;
|
||
|
-moz-flex-direction: row;
|
||
|
-webkit-flex-direction: row;
|
||
|
flex-direction: row;
|
||
|
}
|
||
|
|
||
|
:host(.core-v) {
|
||
|
-webkit-box-orient: vertical;
|
||
|
-ms-flex-direction: column;
|
||
|
-moz-flex-direction: column;
|
||
|
-webkit-flex-direction: column;
|
||
|
flex-direction: column;
|
||
|
}
|
||
|
|
||
|
:host(.core-h.core-reverse) {
|
||
|
-webkit-box-direction: reverse;
|
||
|
-ms-flex-direction: row-reverse;
|
||
|
-moz-flex-direction: row-reverse;
|
||
|
-webkit-flex-direction: row-reverse;
|
||
|
flex-direction: row-reverse;
|
||
|
}
|
||
|
|
||
|
:host(.core-v.core-reverse) {
|
||
|
-webkit-box-direction: reverse;
|
||
|
-ms-flex-direction: column-reverse;
|
||
|
-moz-flex-direction: column-reverse;
|
||
|
-webkit-flex-direction: column-reverse;
|
||
|
flex-direction: column-reverse;
|
||
|
}
|
||
|
|
||
|
/* alignment in main axis */
|
||
|
:host(.core-justify-start) {
|
||
|
-webkit-box-pack: start;
|
||
|
-ms-flex-pack: start;
|
||
|
-moz-justify-content: flex-start;
|
||
|
-webkit-justify-content: flex-start;
|
||
|
justify-content: flex-start;
|
||
|
}
|
||
|
|
||
|
:host(.core-justify-center) {
|
||
|
-webkit-box-pack: center;
|
||
|
-ms-flex-pack: center;
|
||
|
-moz-justify-content: center;
|
||
|
-webkit-justify-content: center;
|
||
|
justify-content: center;
|
||
|
}
|
||
|
|
||
|
:host(.core-justify-end) {
|
||
|
-webkit-box-pack: end;
|
||
|
-ms-flex-pack: end;
|
||
|
-moz-justify-content: flex-end;
|
||
|
-webkit-justify-content: flex-end;
|
||
|
justify-content: flex-end;
|
||
|
}
|
||
|
|
||
|
:host(.core-justify-between) {
|
||
|
-webkit-box-pack: justify;
|
||
|
-ms-flex-pack: justify;
|
||
|
-moz-justify-content: space-between;
|
||
|
-webkit-justify-content: space-between;
|
||
|
justify-content: space-between;
|
||
|
}
|
||
|
|
||
|
/* alignment in cross axis */
|
||
|
:host(.core-align-start) {
|
||
|
-webkit-box-align: start;
|
||
|
-ms-flex-align: start;
|
||
|
-moz-align-items: flex-start;
|
||
|
-webkit-align-items: flex-start;
|
||
|
align-items: flex-start;
|
||
|
}
|
||
|
|
||
|
:host(.core-align-center) {
|
||
|
-webkit-box-align: center;
|
||
|
-ms-flex-align: center;
|
||
|
-moz-align-items: center;
|
||
|
-webkit-align-items: center;
|
||
|
align-items: center;
|
||
|
}
|
||
|
|
||
|
:host(.core-align-end) {
|
||
|
-webkit-box-align: end;
|
||
|
-ms-flex-align: end;
|
||
|
-moz-align-items: flex-end;
|
||
|
-webkit-align-items: flex-end;
|
||
|
align-items: flex-end;
|
||
|
}
|
||
|
</style>
|
||
|
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
|
||
|
(function() {
|
||
|
|
||
|
Polymer('core-layout', {
|
||
|
|
||
|
isContainer: false,
|
||
|
/**
|
||
|
* Controls if the element lays out vertically or not.
|
||
|
*
|
||
|
* @attribute vertical
|
||
|
* @type boolean
|
||
|
* @default false
|
||
|
*/
|
||
|
vertical: false,
|
||
|
/**
|
||
|
* Controls how the items are aligned in the main-axis direction. For
|
||
|
* example for a horizontal layout, this controls how each item is aligned
|
||
|
* horizontally.
|
||
|
*
|
||
|
* @attribute justify
|
||
|
* @type string start|center|end|between
|
||
|
* @default ''
|
||
|
*/
|
||
|
justify: '',
|
||
|
/**
|
||
|
* Controls how the items are aligned in cross-axis direction. For
|
||
|
* example for a horizontal layout, this controls how each item is aligned
|
||
|
* vertically.
|
||
|
*
|
||
|
* @attribute align
|
||
|
* @type string start|center|end
|
||
|
* @default ''
|
||
|
*/
|
||
|
align: '',
|
||
|
/**
|
||
|
* Controls whether or not the items layout in reverse order.
|
||
|
*
|
||
|
* @attribute reverse
|
||
|
* @type boolean
|
||
|
* @default false
|
||
|
*/
|
||
|
reverse: false,
|
||
|
layoutPrefix: 'core-',
|
||
|
|
||
|
// NOTE: include template so that styles are loaded, but remove
|
||
|
// so that we can decide dynamically what part to include
|
||
|
registerCallback: function(polymerElement) {
|
||
|
var template = polymerElement.querySelector('template');
|
||
|
this.styles = template.content.querySelectorAll('style').array();
|
||
|
this.styles.forEach(function(s) {
|
||
|
s.removeAttribute('no-shim');
|
||
|
})
|
||
|
},
|
||
|
|
||
|
fetchTemplate: function() {
|
||
|
return null;
|
||
|
},
|
||
|
|
||
|
attached: function() {
|
||
|
this.installScopeStyle(this.styles[0]);
|
||
|
if (this.children.length) {
|
||
|
this.isContainer = true;
|
||
|
}
|
||
|
var container = this.isContainer ? this : this.parentNode;
|
||
|
// detect if laying out a shadowRoot host.
|
||
|
var forHost = container instanceof ShadowRoot;
|
||
|
if (forHost) {
|
||
|
this.installScopeStyle(this.styles[1], 'host');
|
||
|
container = container.host || document.body;
|
||
|
}
|
||
|
this.layoutContainer = container;
|
||
|
},
|
||
|
|
||
|
detached: function() {
|
||
|
this.layoutContainer = null;
|
||
|
},
|
||
|
|
||
|
layoutContainerChanged: function(old) {
|
||
|
this.style.display = this.layoutContainer === this ? null : 'none';
|
||
|
this.verticalChanged();
|
||
|
this.alignChanged();
|
||
|
this.justifyChanged();
|
||
|
},
|
||
|
|
||
|
setLayoutClass: function(prefix, old, newValue) {
|
||
|
if (this.layoutContainer) {
|
||
|
prefix = this.layoutPrefix + prefix;
|
||
|
if (old) {
|
||
|
this.layoutContainer.classList.remove(prefix + old);
|
||
|
}
|
||
|
if (newValue) {
|
||
|
this.layoutContainer.classList.add(prefix + newValue);
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
verticalChanged: function(old) {
|
||
|
old = old ? 'v' : 'h';
|
||
|
var vertical = this.vertical ? 'v' : 'h';
|
||
|
this.setLayoutClass('', old, vertical);
|
||
|
},
|
||
|
|
||
|
alignChanged: function(old) {
|
||
|
this.setLayoutClass('align-', old, this.align);
|
||
|
},
|
||
|
|
||
|
justifyChanged: function(old) {
|
||
|
this.setLayoutClass('justify-', old, this.justify);
|
||
|
},
|
||
|
|
||
|
reverseChanged: function(old) {
|
||
|
old = old ? 'reverse' : '';
|
||
|
var newValue = this.reverse ? 'reverse' : '';
|
||
|
this.setLayoutClass('', old, newValue);
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
})();
|
||
|
</script>
|
||
|
|
||
|
</polymer-element>
|
||
|
</div>
|
||
|
<div hidden>
|
||
|
<!--
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
-->
|
||
|
<!--
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
-->
|
||
|
|
||
|
<!--
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
-->
|
||
|
|
||
|
<!--
|
||
|
/**
|
||
|
* @group Polymer Core Elements
|
||
|
*
|
||
|
* The `core-iconset-svg` element allows users to define their own icon sets
|
||
|
* that contain svg icons. The svg icon elements should be children of the
|
||
|
* `core-iconset-svg` element. Multiple icons should be given distinct id's.
|
||
|
*
|
||
|
* Using svg elements to create icons has a few advantages over traditional
|
||
|
* bitmap graphics like jpg or png. Icons that use svg are vector based so they
|
||
|
* are resolution independent and should look good on any device. They are
|
||
|
* stylable via css. Icons can be themed, colorized, and even animated.
|
||
|
*
|
||
|
* Example:
|
||
|
*
|
||
|
* <core-iconset-svg id="my-svg-icons" iconSize="24">
|
||
|
* <svg>
|
||
|
* <defs>
|
||
|
* <g id="shape">
|
||
|
* <rect x="50" y="50" width="50" height="50" />
|
||
|
* <circle cx="50" cy="50" r="50" />
|
||
|
* </g>
|
||
|
* </defs>
|
||
|
* </svg>
|
||
|
* </core-iconset-svg>
|
||
|
*
|
||
|
* This will automatically register the icon set "my-svg-icons" to the iconset
|
||
|
* database. To use these icons from within another element, make a
|
||
|
* `core-iconset` element and call the `byId` method
|
||
|
* to retrieve a given iconset. To apply a particular icon inside an
|
||
|
* element use the `applyIcon` method. For example:
|
||
|
*
|
||
|
* iconset.applyIcon(iconNode, 'car');
|
||
|
*
|
||
|
* @element core-iconset-svg
|
||
|
* @extends core-meta
|
||
|
* @homepage github.io
|
||
|
*/
|
||
|
-->
|
||
|
|
||
|
<!--
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
-->
|
||
|
|
||
|
<!--
|
||
|
/**
|
||
|
* @group Polymer Core Elements
|
||
|
*
|
||
|
* The `core-iconset` element allows users to define their own icon sets.
|
||
|
* The `src` property specifies the url of the icon image. Multiple icons may
|
||
|
* be included in this image and they may be organized into rows.
|
||
|
* The `icons` property is a space separated list of names corresponding to the
|
||
|
* icons. The names must be ordered as the icons are ordered in the icon image.
|
||
|
* Icons are expected to be square and are the size specified by the `iconSize`
|
||
|
* property. The `width` property corresponds to the width of the icon image
|
||
|
* and must be specified if icons are arranged into multiple rows in the image.
|
||
|
*
|
||
|
* All `core-iconset` elements are available for use by other `core-iconset`
|
||
|
* elements via a database keyed by id. Typically, an element author that wants
|
||
|
* to support a set of custom icons uses a `core-iconset` to retrieve
|
||
|
* and use another, user-defined iconset.
|
||
|
*
|
||
|
* Example:
|
||
|
*
|
||
|
* <core-iconset id="my-icons" src="my-icons.png" width="96" iconSize="24"
|
||
|
* icons="location place starta stopb bus car train walk">
|
||
|
* </core-iconset>
|
||
|
*
|
||
|
* This will automatically register the icon set "my-icons" to the iconset
|
||
|
* database. To use these icons from within another element, make a
|
||
|
* `core-iconset` element and call the `byId` method to retrieve a
|
||
|
* given iconset. To apply a particular icon to an element, use the
|
||
|
* `applyIcon` method. For example:
|
||
|
*
|
||
|
* iconset.applyIcon(iconNode, 'car');
|
||
|
*
|
||
|
* Themed icon sets are also supported. The `core-iconset` can contain child
|
||
|
* `property` elements that specify a theme with an offsetX and offsetY of the
|
||
|
* theme within the icon resource. For example.
|
||
|
*
|
||
|
* <core-iconset id="my-icons" src="my-icons.png" width="96" iconSize="24"
|
||
|
* icons="location place starta stopb bus car train walk">
|
||
|
* <property theme="special" offsetX="256" offsetY="24"></property>
|
||
|
* </core-iconset>
|
||
|
*
|
||
|
* Then a themed icon can be applied like this:
|
||
|
*
|
||
|
* iconset.applyIcon(iconNode, 'car', 'special');
|
||
|
*
|
||
|
* @element core-iconset
|
||
|
* @extends core-meta
|
||
|
* @homepage github.io
|
||
|
*/
|
||
|
-->
|
||
|
|
||
|
<!--
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
-->
|
||
|
|
||
|
<!--
|
||
|
`core-meta` provides a method of constructing a self-organizing database.
|
||
|
It is useful to collate element meta-data for things like catalogs and for
|
||
|
designer.
|
||
|
|
||
|
Example, an element folder has a `metadata.html` file in it, that contains a
|
||
|
`core-meta`, something like this:
|
||
|
|
||
|
<core-meta id="my-element" label="My Element">
|
||
|
<property name="color" value="blue"></property>
|
||
|
</core-meta>
|
||
|
|
||
|
An application can import as many of these files as it wants, and then use
|
||
|
`core-meta` again to access the collected data.
|
||
|
|
||
|
<script>
|
||
|
var meta = document.createElement('core-meta');
|
||
|
console.log(meta.list); // dump a list of all meta-data elements that have been created
|
||
|
</script>
|
||
|
|
||
|
Use `byId(id)` to retrive a specific core-meta.
|
||
|
|
||
|
<script>
|
||
|
var meta = document.createElement('core-meta');
|
||
|
console.log(meta.byId('my-element'));
|
||
|
</script>
|
||
|
|
||
|
By default all meta-data are stored in a single databse. If your meta-data
|
||
|
have different types and want them to be stored separately, use `type` to
|
||
|
differentiate them.
|
||
|
|
||
|
Example:
|
||
|
|
||
|
<core-meta id="x-foo" type="xElt"></core-meta>
|
||
|
<core-meta id="x-bar" type="xElt"></core-meta>
|
||
|
<core-meta id="y-bar" type="yElt"></core-meta>
|
||
|
|
||
|
<script>
|
||
|
var meta = document.createElement('core-meta');
|
||
|
meta.type = 'xElt';
|
||
|
console.log(meta.list);
|
||
|
</script>
|
||
|
|
||
|
@group Polymer Core Elements
|
||
|
@element core-meta
|
||
|
@homepage github.io
|
||
|
-->
|
||
|
|
||
|
|
||
|
|
||
|
<polymer-element name="core-meta" attributes="list label type" hidden assetpath="../core-meta/">
|
||
|
<script>
|
||
|
|
||
|
(function() {
|
||
|
|
||
|
var SKIP_ID = 'meta';
|
||
|
var metaData = {}, metaArray = {};
|
||
|
|
||
|
Polymer('core-meta', {
|
||
|
|
||
|
/**
|
||
|
* The type of meta-data. All meta-data with the same type with be
|
||
|
* stored together.
|
||
|
*
|
||
|
* @attribute type
|
||
|
* @type string
|
||
|
* @default 'default'
|
||
|
*/
|
||
|
type: 'default',
|
||
|
|
||
|
alwaysPrepare: true,
|
||
|
|
||
|
ready: function() {
|
||
|
this.register(this.id);
|
||
|
},
|
||
|
|
||
|
get metaArray() {
|
||
|
var t = this.type;
|
||
|
if (!metaArray[t]) {
|
||
|
metaArray[t] = [];
|
||
|
}
|
||
|
return metaArray[t];
|
||
|
},
|
||
|
|
||
|
get metaData() {
|
||
|
var t = this.type;
|
||
|
if (!metaData[t]) {
|
||
|
metaData[t] = {};
|
||
|
}
|
||
|
return metaData[t];
|
||
|
},
|
||
|
|
||
|
register: function(id, old) {
|
||
|
if (id && id !== SKIP_ID) {
|
||
|
this.unregister(this, old);
|
||
|
this.metaData[id] = this;
|
||
|
this.metaArray.push(this);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
unregister: function(meta, id) {
|
||
|
delete this.metaData[id || meta.id];
|
||
|
var i = this.metaArray.indexOf(meta);
|
||
|
if (i >= 0) {
|
||
|
this.metaArray.splice(i, 1);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Returns a list of all meta-data elements with the same type.
|
||
|
*
|
||
|
* @attribute list
|
||
|
* @type array
|
||
|
* @default []
|
||
|
*/
|
||
|
get list() {
|
||
|
return this.metaArray;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Retrieves meta-data by ID.
|
||
|
*
|
||
|
* @method byId
|
||
|
* @param {String} id The ID of the meta-data to be returned.
|
||
|
* @returns Returns meta-data.
|
||
|
*/
|
||
|
byId: function(id) {
|
||
|
return this.metaData[id];
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
})();
|
||
|
|
||
|
</script>
|
||
|
</polymer-element>
|
||
|
|
||
|
|
||
|
<polymer-element name="core-iconset" extends="core-meta" attributes="src width icons iconSize" assetpath="../core-iconset/">
|
||
|
|
||
|
<script>
|
||
|
|
||
|
Polymer('core-iconset', {
|
||
|
|
||
|
/**
|
||
|
* The URL of the iconset image.
|
||
|
*
|
||
|
* @attribute src
|
||
|
* @type string
|
||
|
* @default ''
|
||
|
*/
|
||
|
src: '',
|
||
|
|
||
|
/**
|
||
|
* The width of the iconset image. This must only be specified if the
|
||
|
* icons are arranged into separate rows inside the image.
|
||
|
*
|
||
|
* @attribute width
|
||
|
* @type number
|
||
|
* @default 0
|
||
|
*/
|
||
|
width: 0,
|
||
|
|
||
|
/**
|
||
|
* A space separated list of names corresponding to icons in the iconset
|
||
|
* image file. This list must be ordered the same as the icon images
|
||
|
* in the image file.
|
||
|
*
|
||
|
* @attribute icons
|
||
|
* @type string
|
||
|
* @default ''
|
||
|
*/
|
||
|
icons: '',
|
||
|
|
||
|
/**
|
||
|
* The size of an individual icon. Note that icons must be square.
|
||
|
*
|
||
|
* @attribute iconSize
|
||
|
* @type number
|
||
|
* @default 24
|
||
|
*/
|
||
|
iconSize: 24,
|
||
|
|
||
|
/**
|
||
|
* The horizontal offset of the icon images in the inconset src image.
|
||
|
* This is typically used if the image resource contains additional images
|
||
|
* beside those intended for the iconset.
|
||
|
*
|
||
|
* @attribute offsetX
|
||
|
* @type number
|
||
|
* @default 0
|
||
|
*/
|
||
|
offsetX: 0,
|
||
|
/**
|
||
|
* The vertical offset of the icon images in the inconset src image.
|
||
|
* This is typically used if the image resource contains additional images
|
||
|
* beside those intended for the iconset.
|
||
|
*
|
||
|
* @attribute offsetY
|
||
|
* @type number
|
||
|
* @default 0
|
||
|
*/
|
||
|
offsetY: 0,
|
||
|
type: 'iconset',
|
||
|
|
||
|
created: function() {
|
||
|
this.iconMap = {};
|
||
|
this.iconNames = [];
|
||
|
this.themes = {};
|
||
|
},
|
||
|
|
||
|
ready: function() {
|
||
|
// TODO(sorvell): ensure iconset's src is always relative to the main
|
||
|
// document
|
||
|
if (this.src && (this.ownerDocument !== document)) {
|
||
|
this.src = this.resolvePath(this.src, this.ownerDocument.baseURI);
|
||
|
}
|
||
|
this.super();
|
||
|
this.updateThemes();
|
||
|
},
|
||
|
|
||
|
iconsChanged: function() {
|
||
|
var ox = this.offsetX;
|
||
|
var oy = this.offsetY;
|
||
|
this.icons && this.icons.split(/\s+/g).forEach(function(name, i) {
|
||
|
this.iconNames.push(name);
|
||
|
this.iconMap[name] = {
|
||
|
offsetX: ox,
|
||
|
offsetY: oy
|
||
|
}
|
||
|
if (ox + this.iconSize < this.width) {
|
||
|
ox += this.iconSize;
|
||
|
} else {
|
||
|
ox = this.offsetX;
|
||
|
oy += this.iconSize;
|
||
|
}
|
||
|
}, this);
|
||
|
},
|
||
|
|
||
|
updateThemes: function() {
|
||
|
var ts = this.querySelectorAll('property[theme]');
|
||
|
ts && ts.array().forEach(function(t) {
|
||
|
this.themes[t.getAttribute('theme')] = {
|
||
|
offsetX: parseInt(t.getAttribute('offsetX')) || 0,
|
||
|
offsetY: parseInt(t.getAttribute('offsetY')) || 0
|
||
|
};
|
||
|
}, this);
|
||
|
},
|
||
|
|
||
|
// TODO(ffu): support retrived by index e.g. getOffset(10);
|
||
|
/**
|
||
|
* Returns an object containing `offsetX` and `offsetY` properties which
|
||
|
* specify the pixel locaion in the iconset's src file for the given
|
||
|
* `icon` and `theme`. It's uncommon to call this method. It is useful,
|
||
|
* for example, to manually position a css backgroundImage to the proper
|
||
|
* offset. It's more common to use the `applyIcon` method.
|
||
|
*
|
||
|
* @method getOffset
|
||
|
* @param {String|Number} icon The name of the icon or the index of the
|
||
|
* icon within in the icon image.
|
||
|
* @param {String} theme The name of the theme.
|
||
|
* @returns {Object} An object specifying the offset of the given icon
|
||
|
* within the icon resource file; `offsetX` is the horizontal offset and
|
||
|
* `offsetY` is the vertical offset. Both values are in pixel units.
|
||
|
*/
|
||
|
getOffset: function(icon, theme) {
|
||
|
var i = this.iconMap[icon];
|
||
|
if (!i) {
|
||
|
var n = this.iconNames[Number(icon)];
|
||
|
i = this.iconMap[n];
|
||
|
}
|
||
|
var t = this.themes[theme];
|
||
|
if (i && t) {
|
||
|
return {
|
||
|
offsetX: i.offsetX + t.offsetX,
|
||
|
offsetY: i.offsetY + t.offsetY
|
||
|
}
|
||
|
}
|
||
|
return i;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Applies an icon to the given element as a css background image. This
|
||
|
* method does not size the element, and it's often necessary to set
|
||
|
* the element's height and width so that the background image is visible.
|
||
|
*
|
||
|
* @method applyIcon
|
||
|
* @param {Element} element The element to which the background is
|
||
|
* applied.
|
||
|
* @param {String|Number} icon The name or index of the icon to apply.
|
||
|
* @param {String} theme (optional) The name of the theme for the icon.
|
||
|
* @param {Number} scale (optional, defaults to 1) A scaling factor
|
||
|
* with which the icon can be magnified.
|
||
|
*/
|
||
|
applyIcon: function(element, icon, scale) {
|
||
|
var offset = this.getOffset(icon);
|
||
|
scale = scale || 1;
|
||
|
if (element && offset) {
|
||
|
var style = element.style;
|
||
|
style.backgroundImage = 'url(' + this.src + ')';
|
||
|
style.backgroundPosition = (-offset.offsetX * scale + 'px') +
|
||
|
' ' + (-offset.offsetY * scale + 'px');
|
||
|
style.backgroundSize = scale === 1 ? 'auto' :
|
||
|
this.width * scale + 'px';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
</script>
|
||
|
|
||
|
</polymer-element>
|
||
|
|
||
|
|
||
|
<polymer-element name="core-iconset-svg" extends="core-meta" attributes="iconSize" assetpath="../core-iconset-svg/">
|
||
|
|
||
|
<script>
|
||
|
|
||
|
Polymer('core-iconset-svg', {
|
||
|
|
||
|
|
||
|
/**
|
||
|
* The size of an individual icon. Note that icons must be square.
|
||
|
*
|
||
|
* @attribute iconSize
|
||
|
* @type number
|
||
|
* @default 24
|
||
|
*/
|
||
|
iconSize: 24,
|
||
|
type: 'iconset',
|
||
|
|
||
|
created: function() {
|
||
|
this._icons = {};
|
||
|
},
|
||
|
|
||
|
ready: function() {
|
||
|
this.super();
|
||
|
this.updateIcons();
|
||
|
},
|
||
|
|
||
|
iconById: function(id) {
|
||
|
return this._icons[id] || (this._icons[id] = this.querySelector('#' + id));
|
||
|
},
|
||
|
|
||
|
cloneIcon: function(id) {
|
||
|
var icon = this.iconById(id);
|
||
|
if (icon) {
|
||
|
var content = icon.cloneNode(true);
|
||
|
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||
|
svg.setAttribute('viewBox', '0 0 ' + this.iconSize + ' ' +
|
||
|
this.iconSize);
|
||
|
// NOTE(dfreedm): work around https://crbug.com/370136
|
||
|
svg.style.pointerEvents = 'none';
|
||
|
svg.appendChild(content);
|
||
|
return svg;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
get iconNames() {
|
||
|
if (!this._iconNames) {
|
||
|
this._iconNames = this.findIconNames();
|
||
|
}
|
||
|
return this._iconNames;
|
||
|
},
|
||
|
|
||
|
findIconNames: function() {
|
||
|
var icons = this.querySelectorAll('[id]').array();
|
||
|
if (icons.length) {
|
||
|
return icons.map(function(n){ return n.id });
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Applies an icon to the given element. The svg icon is added to the
|
||
|
* element's shadowRoot if one exists or directly to itself.
|
||
|
*
|
||
|
* @method applyIcon
|
||
|
* @param {Element} element The element to which the icon is
|
||
|
* applied.
|
||
|
* @param {String|Number} icon The name the icon to apply.
|
||
|
*/
|
||
|
applyIcon: function(element, icon, scale) {
|
||
|
var root = element.shadowRoot || element;
|
||
|
// remove old
|
||
|
var old = root.querySelector('svg');
|
||
|
if (old) {
|
||
|
old.remove();
|
||
|
}
|
||
|
// install new
|
||
|
var svg = this.cloneIcon(icon);
|
||
|
if (!svg) {
|
||
|
return;
|
||
|
}
|
||
|
var size = scale * this.iconSize;
|
||
|
if (size) {
|
||
|
svg.style.height = svg.style.width = size + 'px';
|
||
|
} else {
|
||
|
svg.setAttribute('height', '100%');
|
||
|
svg.setAttribute('width', '100%');
|
||
|
svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');
|
||
|
}
|
||
|
svg.style.display = 'block';
|
||
|
root.insertBefore(svg, root.firstElementChild);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Tell users of the iconset, that the set has loaded.
|
||
|
* This finds all elements matching the selector argument and calls
|
||
|
* the method argument on them.
|
||
|
* @method updateIcons
|
||
|
* @param selector {string} css selector to identify iconset users,
|
||
|
* defaults to '[icon]'
|
||
|
* @param method {string} method to call on found elements,
|
||
|
* defaults to 'updateIcon'
|
||
|
*/
|
||
|
updateIcons: function(selector, method) {
|
||
|
selector = selector || '[icon]';
|
||
|
method = method || 'updateIcon';
|
||
|
var deep = window.ShadowDOMPolyfill ? '' : 'html /deep/ ';
|
||
|
var i$ = document.querySelectorAll(deep + selector);
|
||
|
for (var i=0, e; e=i$[i]; i++) {
|
||
|
if (e[method]) {
|
||
|
e[method].call(e);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
});
|
||
|
|
||
|
</script>
|
||
|
|
||
|
</polymer-element>
|
||
|
|
||
|
<core-iconset-svg id="icons" iconsize="24">
|
||
|
<svg><defs>
|
||
|
<g id="accessibility"><path d="M12,2c1.1,0,2,0.9,2,2s-0.9,2-2,2s-2-0.9-2-2S10.9,2,12,2z M21,9h-6v13h-2v-6h-2v6H9V9H3V7h18V9z"></path></g>
|
||
|
<g id="account-box"><path d="M3,5l0,14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5c0-1.1-0.9-2-2-2H5C3.9,3,3,3.9,3,5z M15,9c0,1.7-1.3,3-3,3c-1.7,0-3-1.3-3-3c0-1.7,1.3-3,3-3C13.7,6,15,7.3,15,9z M6,17c0-2,4-3.1,6-3.1s6,1.1,6,3.1v1H6V17z"></path></g>
|
||
|
<g id="account-circle"><path d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10c5.5,0,10-4.5,10-10S17.5,2,12,2z M12,5c1.7,0,3,1.3,3,3c0,1.7-1.3,3-3,3c-1.7,0-3-1.3-3-3C9,6.3,10.3,5,12,5z M12,19.2c-2.5,0-4.7-1.3-6-3.2c0-2,4-3.1,6-3.1c2,0,6,1.1,6,3.1C16.7,17.9,14.5,19.2,12,19.2z"></path></g>
|
||
|
<g id="add"><path d="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6V13z"></path></g>
|
||
|
<g id="add-box"><path d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M17,13h-4v4h-2v-4H7v-2h4V7h2v4h4V13z"></path></g>
|
||
|
<g id="add-circle"><path d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10c5.5,0,10-4.5,10-10S17.5,2,12,2z M17,13h-4v4h-2v-4H7v-2h4V7h2v4h4V13z"></path></g>
|
||
|
<g id="add-circle-outline"><path d="M13,7h-2v4H7v2h4v4h2v-4h4v-2h-4V7z M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10c5.5,0,10-4.5,10-10S17.5,2,12,2z M12,20c-4.4,0-8-3.6-8-8s3.6-8,8-8c4.4,0,8,3.6,8,8S16.4,20,12,20z"></path></g>
|
||
|
<g id="android"><path d="M6,18c0,0.6,0.4,1,1,1h1v3.5C8,23.3,8.7,24,9.5,24c0.8,0,1.5-0.7,1.5-1.5V19h2v3.5c0,0.8,0.7,1.5,1.5,1.5c0.8,0,1.5-0.7,1.5-1.5V19h1c0.6,0,1-0.4,1-1V8H6V18z M3.5,8C2.7,8,2,8.7,2,9.5v7C2,17.3,2.7,18,3.5,18C4.3,18,5,17.3,5,16.5v-7C5,8.7,4.3,8,3.5,8z M20.5,8C19.7,8,19,8.7,19,9.5v7c0,0.8,0.7,1.5,1.5,1.5c0.8,0,1.5-0.7,1.5-1.5v-7C22,8.7,21.3,8,20.5,8z M15.5,2.2l1.3-1.3c0.2-0.2,0.2-0.5,0-0.7c-0.2-0.2-0.5-0.2-0.7,0l-1.5,1.5C13.9,1.2,13,1,12,1c-1,0-1.9,0.2-2.7,0.6L7.9,0.1C7.7,0,7.3,0,7.1,0.1C7,0.3,7,0.7,7.1,0.9l1.3,1.3C7,3.3,6,5,6,7h12C18,5,17,3.2,15.5,2.2z M10,5H9V4h1V5z M15,5h-1V4h1V5z"></path></g>
|
||
|
<g id="apps"><path d="M4,8h4V4H4V8z M10,20h4v-4h-4V20z M4,20h4v-4H4V20z M4,14h4v-4H4V14z M10,14h4v-4h-4V14z M16,4v4h4V4H16z M10,8h4V4h-4V8z M16,14h4v-4h-4V14z M16,20h4v-4h-4V20z"></path></g>
|
||
|
<g id="archive"><path d="M20.5,5.2l-1.4-1.7C18.9,3.2,18.5,3,18,3H6C5.5,3,5.1,3.2,4.8,3.5L3.5,5.2C3.2,5.6,3,6,3,6.5V19c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V6.5C21,6,20.8,5.6,20.5,5.2z M12,17.5L6.5,12H10v-2h4v2h3.5L12,17.5z M5.1,5l0.8-1h12l0.9,1H5.1z"></path></g>
|
||
|
<g id="arrow-back"><path d="M20,11H7.8l5.6-5.6L12,4l-8,8l8,8l1.4-1.4L7.8,13H20V11z"></path></g>
|
||
|
<g id="arrow-drop-down"><polygon points="7,10 12,15 17,10 "></polygon></g>
|
||
|
<g id="arrow-drop-down-circle"><path d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10c5.5,0,10-4.5,10-10S17.5,2,12,2z M12,14l-4-4h8L12,14z"></path></g>
|
||
|
<g id="arrow-drop-up"><polygon points="7,14 12,9 17,14 "></polygon></g>
|
||
|
<g id="arrow-forward"><polygon points="12,4 10.6,5.4 16.2,11 4,11 4,13 16.2,13 10.6,18.6 12,20 20,12 "></polygon></g>
|
||
|
<g id="attachment"><path d="M7.5,18c-3,0-5.5-2.5-5.5-5.5S4.5,7,7.5,7H18c2.2,0,4,1.8,4,4s-1.8,4-4,4H9.5C8.1,15,7,13.9,7,12.5S8.1,10,9.5,10H17v1.5H9.5c-0.6,0-1,0.4-1,1s0.4,1,1,1H18c1.4,0,2.5-1.1,2.5-2.5S19.4,8.5,18,8.5H7.5c-2.2,0-4,1.8-4,4s1.8,4,4,4H17V18H7.5z"></path></g>
|
||
|
<g id="backspace"><path d="M22,3H7C6.3,3,5.8,3.3,5.4,3.9L0,12l5.4,8.1C5.8,20.6,6.3,21,7,21h15c1.1,0,2-0.9,2-2V5C24,3.9,23.1,3,22,3z M19,15.6L17.6,17L14,13.4L10.4,17L9,15.6l3.6-3.6L9,8.4L10.4,7l3.6,3.6L17.6,7L19,8.4L15.4,12L19,15.6z"></path></g>
|
||
|
<g id="backup"><path d="M19.4,10c-0.7-3.4-3.7-6-7.4-6C9.1,4,6.6,5.6,5.4,8C2.3,8.4,0,10.9,0,14c0,3.3,2.7,6,6,6h13c2.8,0,5-2.2,5-5C24,12.4,21.9,10.2,19.4,10z M14,13v4h-4v-4H7l5-5l5,5H14z"></path></g>
|
||
|
<g id="block"><path d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10c5.5,0,10-4.5,10-10S17.5,2,12,2z M4,12c0-4.4,3.6-8,8-8c1.8,0,3.5,0.6,4.9,1.7L5.7,16.9C4.6,15.5,4,13.8,4,12z M12,20c-1.8,0-3.5-0.6-4.9-1.7L18.3,7.1C19.4,8.5,20,10.2,20,12C20,16.4,16.4,20,12,20z"></path></g>
|
||
|
<g id="book"><path d="M18,22c1.1,0,2-0.9,2-2V4c0-1.1-0.9-2-2-2h-6v7L9.5,7.5L7,9V2H6C4.9,2,4,2.9,4,4v16c0,1.1,0.9,2,2,2H18z"></path></g>
|
||
|
<g id="bookmark"><path d="M17,3H7C5.9,3,5,3.9,5,5l0,16l7-3l7,3V5C19,3.9,18.1,3,17,3z"></path></g>
|
||
|
<g id="bookmark-outline"><path d="M17,3H7C5.9,3,5,3.9,5,5l0,16l7-3l7,3V5C19,3.9,18.1,3,17,3z M17,18l-5-2.2L7,18V5h10V18z"></path></g>
|
||
|
<g id="bug-report"><path d="M20,8h-2.8c-0.5-0.8-1.1-1.5-1.8-2L17,4.4L15.6,3l-2.2,2.2C13,5.1,12.5,5,12,5s-1,0.1-1.4,0.2L8.4,3L7,4.4L8.6,6C7.9,6.5,7.3,7.2,6.8,8H4v2h2.1C6,10.3,6,10.7,6,11v1H4v2h2v1c0,0.3,0,0.7,0.1,1H4v2h2.8c1,1.8,3,3,5.2,3s4.2-1.2,5.2-3H20v-2h-2.1c0.1-0.3,0.1-0.7,0.1-1v-1h2v-2h-2v-1c0-0.3,0-0.7-0.1-1H20V8z M14,16h-4v-2h4V16z M14,12h-4v-2h4V12z"></path></g>
|
||
|
<g id="cancel"><path d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10c5.5,0,10-4.5,10-10S17.5,2,12,2z M17,15.6L15.6,17L12,13.4L8.4,17L7,15.6l3.6-3.6L7,8.4L8.4,7l3.6,3.6L15.6,7L17,8.4L13.4,12L17,15.6z"></path></g>
|
||
|
<g id="check"><polygon points="9,16.2 4.8,12 3.4,13.4 9,19 21,7 19.6,5.6 "></polygon></g>
|
||
|
<g id="check-box"><path d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M10,17l-5-5l1.4-1.4l3.6,3.6l7.6-7.6L19,8L10,17z"></path></g>
|
||
|
<g id="check-box-blank"><path d="M19,3H5C3.9,3,3,3.9,3,5l0,14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z"></path></g>
|
||
|
<g id="check-box-outline"><path d="M7.9,10.1l-1.4,1.4L11,16L21,6l-1.4-1.4L11,13.2L7.9,10.1z M19,19L5,19V5h10V3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2v-8h-2V19z"></path></g>
|
||
|
<g id="check-box-outline-blank"><path d="M19,5v14L5,19V5H19 M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3L19,3z"></path></g>
|
||
|
<g id="check-circle"><path d="M12,2C6.5,2,2,6.5,2,12c0,5.5,4.5,10,10,10c5.5,0,10-4.5,10-10C22,6.5,17.5,2,12,2z M10,17l-5-5l1.4-1.4l3.6,3.6l7.6-7.6L19,8L10,17z"></path></g>
|
||
|
<g id="check-circle-blank"><path d="M12,2C6.5,2,2,6.5,2,12c0,5.5,4.5,10,10,10c5.5,0,10-4.5,10-10C22,6.5,17.5,2,12,2z"></path></g>
|
||
|
<g id="check-circle-outline"><path d="M7.9,10.1l-1.4,1.4L11,16L21,6l-1.4-1.4L11,13.2L7.9,10.1z M20,12c0,4.4-3.6,8-8,8s-8-3.6-8-8s3.6-8,8-8c0.8,0,1.5,0.1,2.2,0.3l1.6-1.6C14.6,2.3,13.3,2,12,2C6.5,2,2,6.5,2,12s4.5,10,10,10s10-4.5,10-10H20z"></path></g>
|
||
|
<g id="check-circle-outline-blank"><path d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10c5.5,0,10-4.5,10-10S17.5,2,12,2z M12,20c-4.4,0-8-3.6-8-8s3.6-8,8-8c4.4,0,8,3.6,8,8S16.4,20,12,20z"></path></g>
|
||
|
<g id="chevron-left"><polygon points="15.4,7.4 14,6 8,12 14,18 15.4,16.6 10.8,12 "></polygon></g>
|
||
|
<g id="chevron-right"><polygon points="10,6 8.6,7.4 13.2,12 8.6,16.6 10,18 16,12 "></polygon></g>
|
||
|
<g id="clear"><polygon points="19,6.4 17.6,5 12,10.6 6.4,5 5,6.4 10.6,12 5,17.6 6.4,19 12,13.4 17.6,19 19,17.6 13.4,12 "></polygon></g>
|
||
|
<g id="close"><polygon points="19,6.4 17.6,5 12,10.6 6.4,5 5,6.4 10.6,12 5,17.6 6.4,19 12,13.4 17.6,19 19,17.6 13.4,12 "></polygon></g>
|
||
|
<g id="cloud"><path d="M19.4,10c-0.7-3.4-3.7-6-7.4-6C9.1,4,6.6,5.6,5.4,8C2.3,8.4,0,10.9,0,14c0,3.3,2.7,6,6,6h13c2.8,0,5-2.2,5-5C24,12.4,21.9,10.2,19.4,10z"></path></g>
|
||
|
<g id="cloud-circle"><path d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10c5.5,0,10-4.5,10-10S17.5,2,12,2z M17,15H8H7.5C6.1,15,5,13.9,5,12.5S6.1,10,7.5,10h0.6c0.4-1.7,2-3,3.9-3c2.2,0,4,1.8,4,4h1c1.1,0,2,0.9,2,2S18.1,15,17,15z"></path></g>
|
||
|
<g id="cloud-done"><path d="M19.4,10c-0.7-3.4-3.7-6-7.4-6C9.1,4,6.6,5.6,5.4,8C2.3,8.4,0,10.9,0,14c0,3.3,2.7,6,6,6h13c2.8,0,5-2.2,5-5C24,12.4,21.9,10.2,19.4,10z M10,17l-3.5-3.5l1.4-1.4l2.1,2.1L15.2,9l1.4,1.4L10,17z"></path></g>
|
||
|
<g id="cloud-download"><path d="M19.4,10c-0.7-3.4-3.7-6-7.4-6C9.1,4,6.6,5.6,5.4,8C2.3,8.4,0,10.9,0,14c0,3.3,2.7,6,6,6h13c2.8,0,5-2.2,5-5C24,12.4,21.9,10.2,19.4,10z M17,13l-5,5l-5-5h3V9h4v4H17z"></path></g>
|
||
|
<g id="cloud-off"><path d="M19.4,10c-0.7-3.4-3.7-6-7.4-6c-1.5,0-2.9,0.4-4,1.2l1.5,1.5C10.2,6.2,11.1,6,12,6c3,0,5.5,2.5,5.5,5.5V12H19c1.7,0,3,1.3,3,3c0,1.1-0.6,2.1-1.6,2.6l1.5,1.5c1.3-0.9,2.1-2.4,2.1-4.1C24,12.4,21.9,10.2,19.4,10z M3,5.3L5.8,8C2.6,8.2,0,10.8,0,14c0,3.3,2.7,6,6,6h11.7l2,2l1.3-1.3L4.3,4L3,5.3z M7.7,10l8,8H6c-2.2,0-4-1.8-4-4c0-2.2,1.8-4,4-4H7.7z"></path></g>
|
||
|
<g id="cloud-queue"><path d="M19.4,10c-0.7-3.4-3.7-6-7.4-6C9.1,4,6.6,5.6,5.4,8C2.3,8.4,0,10.9,0,14c0,3.3,2.7,6,6,6h13c2.8,0,5-2.2,5-5C24,12.4,21.9,10.2,19.4,10z M19,18H6c-2.2,0-4-1.8-4-4c0-2.2,1.8-4,4-4h0.7C7.4,7.7,9.5,6,12,6c3,0,5.5,2.5,5.5,5.5V12H19c1.7,0,3,1.3,3,3S20.7,18,19,18z"></path></g>
|
||
|
<g id="cloud-upload"><path d="M19.4,10c-0.7-3.4-3.7-6-7.4-6C9.1,4,6.6,5.6,5.4,8C2.3,8.4,0,10.9,0,14c0,3.3,2.7,6,6,6h13c2.8,0,5-2.2,5-5C24,12.4,21.9,10.2,19.4,10z M14,13v4h-4v-4H7l5-5l5,5H14z"></path></g>
|
||
|
<g id="content-copy"><path d="M16,1H4C2.9,1,2,1.9,2,3v14h2V3h12V1z M19,5H8C6.9,5,6,5.9,6,7v14c0,1.1,0.9,2,2,2h11c1.1,0,2-0.9,2-2V7C21,5.9,20.1,5,19,5z M19,21H8V7h11V21z"></path></g>
|
||
|
<g id="content-cut"><path d="M10,6c0-2.2-1.8-4-4-4S2,3.8,2,6c0,2.2,1.8,4,4,4c0.6,0,1.1-0.1,1.6-0.4L10,12l-2.4,2.4C7.1,14.1,6.6,14,6,14c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4s4-1.8,4-4c0-0.6-0.1-1.1-0.4-1.6L12,14l7,7h4L9.6,7.6C9.9,7.1,10,6.6,10,6z M6,8C4.9,8,4,7.1,4,6s0.9-2,2-2c1.1,0,2,0.9,2,2S7.1,8,6,8z M6,20c-1.1,0-2-0.9-2-2s0.9-2,2-2c1.1,0,2,0.9,2,2S7.1,20,6,20z M12,11.5c0.3,0,0.5,0.2,0.5,0.5c0,0.3-0.2,0.5-0.5,0.5c-0.3,0-0.5-0.2-0.5-0.5C11.5,11.7,11.7,11.5,12,11.5z M23,3h-4l-6,6l2,2L23,3z"></path></g>
|
||
|
<g id="content-paste"><path d="M19,2h-4.2c-0.4-1.2-1.5-2-2.8-2c-1.3,0-2.4,0.8-2.8,2H5C3.9,2,3,2.9,3,4v16c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V4C21,2.9,20.1,2,19,2z M12,2c0.6,0,1,0.4,1,1s-0.4,1-1,1c-0.6,0-1-0.4-1-1S11.4,2,12,2z M19,20H5V4h2v3h10V4h2V20z"></path></g>
|
||
|
<g id="create"><path d="M3,17.2V21h3.8L17.8,9.9l-3.8-3.8L3,17.2z M20.7,7c0.4-0.4,0.4-1,0-1.4l-2.3-2.3c-0.4-0.4-1-0.4-1.4,0l-1.8,1.8l3.8,3.8L20.7,7z"></path></g>
|
||
|
<g id="credit-card"><path d="M20,4H4C2.9,4,2,4.9,2,6v12c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V6C22,4.9,21.1,4,20,4z M20,18H4v-6h16V18z M20,8H4V6h16V8z"></path></g>
|
||
|
<g id="delete"><path d="M6,19c0,1.1,0.9,2,2,2h8c1.1,0,2-0.9,2-2V7H6V19z M19,4h-3.5l-1-1h-5l-1,1H5v2h14V4z"></path></g>
|
||
|
<g id="done"><polygon points="9,16.2 4.8,12 3.4,13.4 9,19 21,7 19.6,5.6 "></polygon></g>
|
||
|
<g id="done-all"><path d="M18,7l-1.4-1.4l-6.3,6.3l1.4,1.4L18,7z M22.2,5.6L11.7,16.2L7.5,12l-1.4,1.4l5.6,5.6l12-12L22.2,5.6z M0.4,13.4L6,19l1.4-1.4L1.8,12L0.4,13.4z"></path></g>
|
||
|
<g id="drafts"><path d="M22,8c0-0.7-0.4-1.3-0.9-1.7L12,1L2.9,6.3C2.4,6.7,2,7.3,2,8v10c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2L22,8z M12,13L3.7,7.8L12,3l8.3,4.8L12,13z"></path></g>
|
||
|
<g id="drive"><path d="M22.3,14L15.4,2H8.6l0,0l6.9,12H22.3z M9.7,15l-3.4,6h13.1l3.4-6H9.7z M7.7,3.5L1.2,15l3.4,6l6.6-11.5L7.7,3.5z"></path></g>
|
||
|
<g id="drawer"><path d="M20,4H4C2.8,4,2,4.8,2,6v12c0,1.2,0.8,2,2,2h16c1,0,2-0.8,2-2V6C22,4.8,21,4,20,4z M20,18h-6V6h6V18z"></path></g>
|
||
|
<g id="drive-document"><path d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M17,9H7V7h10V9z M17,13H7v-2h10V13z M14,17H7v-2h7V17z"></path></g>
|
||
|
<g id="drive-drawing"><path d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M18,18h-6v-5.8c-0.7,0.6-1.5,1-2.5,1c-2,0-3.7-1.7-3.7-3.7s1.7-3.7,3.7-3.7c2,0,3.7,1.7,3.7,3.7c0,1-0.4,1.8-1,2.5H18V18z"></path></g>
|
||
|
<g id="drive-file"><path d="M6,2C4.9,2,4,2.9,4,4l0,16c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V8l-6-6H6z M13,9V3.5L18.5,9H13z"></path></g>
|
||
|
<g id="drive-form"><path d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M9,17H7v-2h2V17z M9,13H7v-2h2V13z M9,9H7V7h2V9z M17,17h-7v-2h7V17z M17,13h-7v-2h7V13z M17,9h-7V7h7V9z"></path></g>
|
||
|
<g id="drive-fusiontable"><path d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M19,10.2L13,17l-4-4l-4,4v-3l4-4l4,4l6-6.8V10.2z"></path></g>
|
||
|
<g id="drive-image"><path d="M21,19V5c0-1.1-0.9-2-2-2H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14C20.1,21,21,20.1,21,19z M8.5,13.5l2.5,3l3.5-4.5l4.5,6H5L8.5,13.5z"></path></g>
|
||
|
<g id="drive-ms-excel"><path d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M16.2,17h-2L12,13.2L9.8,17h-2l3.2-5L7.8,7h2l2.2,3.8L14.2,7h2L13,12L16.2,17z"></path></g>
|
||
|
<g id="drive-ms-powerpoint"><path d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M9.8,13.4V17H8V7h4.3c1.5,0,2.2,0.3,2.8,0.9c0.7,0.6,0.9,1.4,0.9,2.3c0,1-0.3,1.8-0.9,2.3c-0.6,0.5-1.3,0.8-2.8,0.8H9.8z"></path><path d="M9.8,12V8.4h2.3c0.7,0,1.2,0.2,1.5,0.6c0.3,0.4,0.5,0.7,0.5,1.2c0,0.6-0.2,0.9-0.5,1.3c-0.3,0.3-0.7,0.5-1.4,0.5H9.8z"></path></g>
|
||
|
<g id="drive-ms-word"><path d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M15.5,17H14l-2-7.5L10,17H8.5L6.1,7h1.7l1.5,7.5l2-7.5h1.4l2,7.5L16.2,7h1.7L15.5,17z"></path></g>
|
||
|
<g id="drive-pdf"><path d="M11.3,8.6L11.3,8.6C11.4,8.6,11.4,8.6,11.3,8.6c0.1-0.4,0.2-0.6,0.2-0.9l0-0.2c0.1-0.5,0.1-0.9,0-1c0,0,0,0,0-0.1l-0.1-0.1c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0.1-0.1,0.1C11.1,7,11.1,7.7,11.3,8.6C11.3,8.6,11.3,8.6,11.3,8.6z M8.3,15.5c-0.2,0.1-0.4,0.2-0.5,0.3c-0.7,0.6-1.2,1.3-1.3,1.6c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0C7.1,17.3,7.7,16.7,8.3,15.5C8.4,15.5,8.4,15.5,8.3,15.5C8.4,15.5,8.3,15.5,8.3,15.5z M17.5,14c-0.1-0.1-0.5-0.4-1.9-0.4c-0.1,0-0.1,0-0.2,0c0,0,0,0,0,0c0,0,0,0,0,0.1c0.7,0.3,1.4,0.5,1.9,0.5c0.1,0,0.1,0,0.2,0l0,0c0,0,0.1,0,0.1,0c0,0,0,0,0-0.1c0,0,0,0,0,0C17.6,14.1,17.5,14.1,17.5,14z M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M17.9,14.8C17.7,14.9,17.4,15,17,15c-0.8,0-2-0.2-3-0.7c-1.7,0.2-3,0.4-4,0.8c-0.1,0-0.1,0-0.2,0.1c-1.2,2.1-2.2,3.1-3,3.1c-0.2,0-0.3,0-0.4-0.1l-0.5-0.3l0-0.1c-0.1-0.2-0.1-0.3-0.1-0.5c0.1-0.5,0.7-1.4,1.9-2.1c0.2-0.1,0.5-0.3,0.9-0.5c0.3-0.5,0.6-1.1,1-1.8c0.5-1,0.8-2,1.1-2.9l0,0c-0.4-1.2-0.6-1.9-0.2-3.3c0.1-0.4,0.4-0.8,0.8-0.8l0.2,0c0.2,0,0.4,0.1,0.6,0.2c0.7,0.7,0.4,2.3,0,3.6c0,0.1,0,0.1,0,0.1c0.4,1.1,1,2,1.6,2.6c0.3,0.2,0.5,0.4,0.9,0.6c0.5,0,0.9-0.1,1.3-0.1c1.2,0,2,0.2,2.3,0.7c0.1,0.2,0.1,0.4,0.1,0.6C18.2,14.3,18.1,14.6,17.9,14.8z M11.4,10.9c-0.2,0.7-0.6,1.5-1,2.4c-0.2,0.4-0.4,0.7-0.6,1.1c0,0,0.1,0,0.1,0l0.1,0v0c1.3-0.5,2.5-0.8,3.3-0.9c-0.2-0.1-0.3-0.2-0.4-0.3C12.4,12.6,11.8,11.8,11.4,10.9z"></path></g>
|
||
|
<g id="drive-presentation"><path d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M19,16H5V8h14V16z"></path></g>
|
||
|
<g id="drive-script"><path d="M19,3H5C3.9,3,3,3.9,3,5l0,4h0v6h0l0,4c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M11,17v-3H5v-4h6V7l5,5L11,17z"></path></g>
|
||
|
<g id="drive-site"><path d="M19,4H5C3.9,4,3,4.9,3,6l0,12c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V6C21,4.9,20.1,4,19,4z M14,18H5v-4h9V18z M14,13H5V9h9V13z M19,18h-4V9h4V18z"></path></g>
|
||
|
<g id="drive-spreadsheet"><path d="M19,3H5C3.9,3,3,3.9,3,5l0,3h0v11c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M19,11h-8v8H9v-8H5V9h4V5h2v4h8V11z"></path></g>
|
||
|
<g id="drive-video"><path d="M18,4l2,4h-3l-2-4h-2l2,4h-3l-2-4H8l2,4H7L5,4H4C2.9,4,2,4.9,2,6l0,12c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V4H18z"></path></g>
|
||
|
<g id="error"><path d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10c5.5,0,10-4.5,10-10S17.5,2,12,2z M13,17h-2v-2h2V17z M13,13h-2V7h2V13z"></path></g>
|
||
|
<g id="event"><path d="M17,12h-5v5h5V12z M16,1v2H8V1H6v2H5C3.9,3,3,3.9,3,5l0,14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5c0-1.1-0.9-2-2-2h-1V1H16z M19,19H5V8h14V19z"></path></g>
|
||
|
<g id="exit-to-app"><path d="M10.1,15.6l1.4,1.4l5-5l-5-5l-1.4,1.4l2.6,2.6H3v2h9.7L10.1,15.6z M19,3H5C3.9,3,3,3.9,3,5v4h2V5h14v14H5v-4H3v4c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z"></path></g>
|
||
|
<g id="expand-less"><polygon points="12,8 6,14 7.4,15.4 12,10.8 16.6,15.4 18,14 "></polygon></g>
|
||
|
<g id="expand-more"><polygon points="16.6,8.6 12,13.2 7.4,8.6 6,10 12,16 18,10 "></polygon></g>
|
||
|
<g id="explore"><path d="M12,10.9c-0.6,0-1.1,0.5-1.1,1.1s0.5,1.1,1.1,1.1c0.6,0,1.1-0.5,1.1-1.1S12.6,10.9,12,10.9z M12,2C6.5,2,2,6.5,2,12c0,5.5,4.5,10,10,10c5.5,0,10-4.5,10-10C22,6.5,17.5,2,12,2z M14.2,14.2L6,18l3.8-8.2L18,6L14.2,14.2z"></path></g>
|
||
|
<g id="extension"><path d="M20.5,11H19V7c0-1.1-0.9-2-2-2h-4V3.5C13,2.1,11.9,1,10.5,1C9.1,1,8,2.1,8,3.5V5H4C2.9,5,2,5.9,2,7l0,3.8h1.5c1.5,0,2.7,1.2,2.7,2.7S5,16.2,3.5,16.2H2L2,20c0,1.1,0.9,2,2,2h3.8v-1.5c0-1.5,1.2-2.7,2.7-2.7c1.5,0,2.7,1.2,2.7,2.7V22H17c1.1,0,2-0.9,2-2v-4h1.5c1.4,0,2.5-1.1,2.5-2.5S21.9,11,20.5,11z"></path></g>
|
||
|
<g id="favorite"><path d="M12,21.4L10.6,20C5.4,15.4,2,12.3,2,8.5C2,5.4,4.4,3,7.5,3c1.7,0,3.4,0.8,4.5,2.1C13.1,3.8,14.8,3,16.5,3C19.6,3,22,5.4,22,8.5c0,3.8-3.4,6.9-8.6,11.5L12,21.4z"></path></g>
|
||
|
<g id="favorite-outline"><path d="M16.5,3c-1.7,0-3.4,0.8-4.5,2.1C10.9,3.8,9.2,3,7.5,3C4.4,3,2,5.4,2,8.5c0,3.8,3.4,6.9,8.6,11.5l1.4,1.3l1.4-1.3c5.1-4.7,8.6-7.8,8.6-11.5C22,5.4,19.6,3,16.5,3z M12.1,18.6L12,18.6l-0.1-0.1C7.1,14.2,4,11.4,4,8.5C4,6.5,5.5,5,7.5,5c1.5,0,3,1,3.6,2.4h1.9C13.5,6,15,5,16.5,5c2,0,3.5,1.5,3.5,3.5C20,11.4,16.9,14.2,12.1,18.6z"></path></g>
|
||
|
<g id="file-download"><path d="M19,9h-4V3H9v6H5l7,7L19,9z M5,18v2h14v-2H5z"></path></g>
|
||
|
<g id="file-upload"><polygon points="9,16 15,16 15,10 19,10 12,3 5,10 9,10 "><rect x="5" y="18" width="14" height="2"></rect></polygon></g>
|
||
|
<g id="filter"><path d="M10,18h4v-2h-4V18z M3,6v2h18V6H3z M6,13h12v-2H6V13z"></path></g>
|
||
|
<g id="flag"><polygon points="14.4,6 14,4 5,4 5,21 7,21 7,14 12.6,14 13,16 20,16 20,6 "></polygon></g>
|
||
|
<g id="flip-to-back"><path d="M9,7H7l0,2h2V7z M9,11H7v2h2V11z M9,3C7.9,3,7,3.9,7,5h2V3z M13,15h-2v2h2V15z M19,3v2h2C21,3.9,20.1,3,19,3z M13,3h-2v2h2V3z M9,17v-2H7C7,16.1,7.9,17,9,17z M19,13h2v-2h-2V13z M19,9h2V7h-2V9z M19,17c1.1,0,2-0.9,2-2h-2V17z M5,7H3v2h0l0,10c0,1.1,0.9,2,2,2h12v-2H5V7z M15,5h2V3h-2V5z M15,17h2v-2h-2V17z"></path></g>
|
||
|
<g id="flip-to-front"><path d="M3,13h2v-2H3L3,13z M3,17h2v-2H3V17z M5,21v-2H3C3,20.1,3.9,21,5,21z M3,9h2V7H3V9z M15,21h2v-2h-2V21z M19,3H9C7.9,3,7,3.9,7,5v2h0v2v6c0,1.1,0.9,2,2,2h5h4h1c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M19,15H9V5h10V15z M11,21h2v-2h-2V21z M7,21h2v-2H7V21z"></path></g>
|
||
|
<g id="folder"><path d="M10,4H4C2.9,4,2,4.9,2,6l0,12c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V8c0-1.1-0.9-2-2-2h-8L10,4z"></path></g>
|
||
|
<g id="folder-mydrive"><path d="M20,6h-8l-2-2H4C2.9,4,2,4.9,2,6l0,12c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V8C22,6.9,21.1,6,20,6z M11.7,17l-1.3-2.1l2.8-5l1.5,2.7L12.3,17H11.7z M18.3,17h-5.5l1.4-2.5h5.1l0.3,0.5L18.3,17z M13.8,9h2.4l2.8,5H16l-2.6-4.5L13.8,9z"></path></g>
|
||
|
<g id="folder-shared"><path d="M20,6h-8l-2-2H4C2.9,4,2,4.9,2,6l0,12c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V8C22,6.9,21.1,6,20,6z M15,9c1.1,0,2,0.9,2,2c0,1.1-0.9,2-2,2c-1.1,0-2-0.9-2-2C13,9.9,13.9,9,15,9z M19,17h-8v-1c0-1.3,2.7-2,4-2c1.3,0,4,0.7,4,2V17z"></path></g>
|
||
|
<g id="forward"><polygon points="12,8 12,4 20,12 12,20 12,16 4,16 4,8 "></polygon></g>
|
||
|
<g id="fullscreen"><path d="M7,14H5v5h5v-2H7V14z M5,10h2V7h3V5H5V10z M17,17h-3v2h5v-5h-2V17z M14,5v2h3v3h2V5H14z"></path></g>
|
||
|
<g id="fullscreen-exit"><path d="M5,16h3v3h2v-5H5V16z M8,8H5v2h5V5H8V8z M14,19h2v-3h3v-2h-5V19z M16,8V5h-2v5h5V8H16z"></path></g>
|
||
|
<g id="gesture"><path d="M4.6,6.9C5.3,6.2,6,5.5,6.3,5.7c0.5,0.2,0,1-0.3,1.5c-0.3,0.4-2.9,3.9-2.9,6.3c0,1.3,0.5,2.3,1.3,3c0.8,0.6,1.7,0.7,2.6,0.5c1.1-0.3,1.9-1.4,3.1-2.8c1.2-1.5,2.8-3.4,4.1-3.4c1.6,0,1.6,1,1.8,1.8c-3.8,0.6-5.4,3.7-5.4,5.4c0,1.7,1.4,3.1,3.2,3.1c1.6,0,4.3-1.3,4.7-6.1H21v-2.5h-2.5c-0.2-1.6-1.1-4.2-4-4.2c-2.2,0-4.2,1.9-4.9,2.8c-0.6,0.7-2.1,2.5-2.3,2.7c-0.3,0.3-0.7,0.8-1.1,0.8c-0.4,0-0.7-0.8-0.4-1.9c0.4-1.1,1.4-2.9,1.9-3.5C8.4,8,8.9,7.2,8.9,5.9C8.9,3.7,7.3,3,6.4,3C5.1,3,4,4,3.7,4.3C3.4,4.6,3.1,4.9,2.8,5.2L4.6,6.9z M13.9,18.6c-0.3,0-0.7-0.3-0.7-0.7c0-0.6,0.7-2.2,2.9-2.8C15.7,17.8,14.6,18.6,13.9,18.6z"></path></g>
|
||
|
<g id="google"><path d="M16.3,13.4l-1.1-0.8c-0.4-0.3-0.8-0.7-0.8-1.4c0-0.7,0.5-1.3,1-1.6c1.3-1,2.6-2.1,2.6-4.3c0-2.1-1.3-3.3-2-3.9h1.7L18.9,0h-6.2C8.3,0,6.1,2.8,6.1,5.8c0,2.3,1.8,4.8,5,4.8h0.8c-0.1,0.3-0.4,0.8-0.4,1.3c0,1,0.4,1.4,0.9,2c-1.4,0.1-4,0.4-5.9,1.6c-1.8,1.1-2.3,2.6-2.3,3.7c0,2.3,2.1,4.5,6.6,4.5c5.4,0,8-3,8-5.9C18.8,15.7,17.7,14.6,16.3,13.4z M8.7,4.3c0-2.2,1.3-3.2,2.7-3.2c2.6,0,4,3.5,4,5.5c0,2.6-2.1,3.1-2.9,3.1C10,9.7,8.7,6.6,8.7,4.3z M12.3,22.3c-3.3,0-5.4-1.5-5.4-3.7c0-2.2,2-2.9,2.6-3.2c1.3-0.4,3-0.5,3.3-0.5c0.3,0,0.5,0,0.7,0c2.4,1.7,3.4,2.4,3.4,4C16.9,20.8,15,22.3,12.3,22.3z"></path></g>
|
||
|
<g id="google-plus"><path d="M21,10V7h-2v3h-3v2h3v3h2v-3h3v-2H21z M13.3,13.4l-1.1-0.8c-0.4-0.3-0.8-0.7-0.8-1.4c0-0.7,0.5-1.3,1-1.6c1.3-1,2.6-2.1,2.6-4.3c0-2.1-1.3-3.3-2-3.9h1.7L15.9,0H9.7C5.3,0,3.1,2.8,3.1,5.8c0,2.3,1.8,4.8,5,4.8h0.8c-0.1,0.3-0.4,0.8-0.4,1.3c0,1,0.4,1.4,0.9,2c-1.4,0.1-4,0.4-5.9,1.6c-1.8,1.1-2.3,2.6-2.3,3.7c0,2.3,2.1,4.5,6.6,4.5c5.4,0,8-3,8-5.9C15.8,15.7,14.7,14.6,13.3,13.4z M5.7,4.3c0-2.2,1.3-3.2,2.7-3.2c2.6,0,4,3.5,4,5.5c0,2.6-2.1,3.1-2.9,3.1C7,9.7,5.7,6.6,5.7,4.3z M9.3,22.3c-3.3,0-5.4-1.5-5.4-3.7c0-2.2,2-2.9,2.6-3.2c1.3-0.4,3-0.5,3.3-0.5c0.3,0,0.5,0,0.7,0c2.4,1.7,3.4,2.4,3.4,4C13.9,20.8,12,22.3,9.3,22.3z"></path></g>
|
||
|
<g id="help"><path d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10c5.5,0,10-4.5,10-10S17.5,2,12,2z M13,19h-2v-2h2V19z M15.1,11.3l-0.9,0.9C13.4,12.9,13,13.5,13,15h-2v-0.5c0-1.1,0.4-2.1,1.2-2.8l1.2-1.3C13.8,10.1,14,9.6,14,9c0-1.1-0.9-2-2-2c-1.1,0-2,0.9-2,2H8c0-2.2,1.8-4,4-4c2.2,0,4,1.8,4,4C16,9.9,15.6,10.7,15.1,11.3z"></path></g>
|
||
|
<g id="history"><path opacity="0.9" d="M12.5,2C9,2,5.9,3.9,4.3,6.8L2,4.5V11h6.5L5.7,8.2C7,5.7,9.5,4,12.5,4c4.1,0,7.5,3.4,7.5,7.5c0,4.1-3.4,7.5-7.5,7.5c-3.3,0-6-2.1-7.1-5H3.3c1.1,4,4.8,7,9.2,7c5.3,0,9.5-4.3,9.5-9.5S17.7,2,12.5,2z M11,7v5.1l4.7,2.8l0.8-1.3l-4-2.4V7H11z"></path></g>
|
||
|
<g id="home"><polygon points="10,20 10,14 14,14 14,20 19,20 19,12 22,12 12,3 2,12 5,12 5,20 "></polygon></g>
|
||
|
<g id="https"><path d="M18,8h-1V6c0-2.8-2.2-5-5-5C9.2,1,7,3.2,7,6v2H6c-1.1,0-2,0.9-2,2v10c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V10C20,8.9,19.1,8,18,8z M12,17c-1.1,0-2-0.9-2-2s0.9-2,2-2c1.1,0,2,0.9,2,2S13.1,17,12,17z M15.1,8H8.9V6c0-1.7,1.4-3.1,3.1-3.1c1.7,0,3.1,1.4,3.1,3.1V8z"></path></g>
|
||
|
<g id="inbox"><path d="M19,3H5C3.9,3,3,3.9,3,5l0,14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M19,15h-4c0,1.7-1.3,3-3,3c-1.7,0-3-1.3-3-3H5V5h14V15z M16,10h-2V7h-4v3H8l4,4L16,10z"></path></g>
|
||
|
<g id="info"><path d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10c5.5,0,10-4.5,10-10S17.5,2,12,2z M13,17h-2v-6h2V17z M13,9h-2V7h2V9z"></path></g>
|
||
|
<g id="info-outline"><path d="M11,17h2v-6h-2V17z M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10c5.5,0,10-4.5,10-10S17.5,2,12,2z M12,20c-4.4,0-8-3.6-8-8s3.6-8,8-8c4.4,0,8,3.6,8,8S16.4,20,12,20z M11,9h2V7h-2V9z"></path></g>
|
||
|
<g id="invert-colors"><path d="M17,12c0-2.8-2.2-5-5-5v10C14.8,17,17,14.8,17,12z M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M19,19h-7v-2c-2.8,0-5-2.2-5-5s2.2-5,5-5V5h7V19z"></path></g>
|
||
|
<g id="keep"><path d="M16,12V4h1V2H7v2h1v8l-2,2v2h5.2v6h1.6v-6H18v-2L16,12z"></path></g>
|
||
|
<g id="label"><path d="M17.6,5.8C17.3,5.3,16.7,5,16,5L5,5C3.9,5,3,5.9,3,7v10c0,1.1,0.9,2,2,2l11,0c0.7,0,1.3-0.3,1.6-0.8L22,12L17.6,5.8z"></path></g>
|
||
|
<g id="label-outline"><path d="M17.6,5.8C17.3,5.3,16.7,5,16,5L5,5C3.9,5,3,5.9,3,7v10c0,1.1,0.9,2,2,2l11,0c0.7,0,1.3-0.3,1.6-0.8L22,12L17.6,5.8z M16,17H5V7h11l3.5,5L16,17z"></path></g>
|
||
|
<g id="language"><path d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10c5.5,0,10-4.5,10-10S17.5,2,12,2z M18.9,8H16c-0.3-1.3-0.8-2.4-1.4-3.6C16.4,5.1,18,6.3,18.9,8z M12,4c0.8,1.2,1.5,2.5,1.9,4h-3.8C10.5,6.6,11.2,5.2,12,4z M4.3,14C4.1,13.4,4,12.7,4,12s0.1-1.4,0.3-2h3.4c-0.1,0.7-0.1,1.3-0.1,2s0.1,1.3,0.1,2H4.3z M5.1,16H8c0.3,1.3,0.8,2.4,1.4,3.6C7.6,18.9,6,17.7,5.1,16z M8,8H5.1c1-1.7,2.5-2.9,4.3-3.6C8.8,5.6,8.3,6.7,8,8z M12,20c-0.8-1.2-1.5-2.5-1.9-4h3.8C13.5,17.4,12.8,18.8,12,20z M14.3,14H9.7c-0.1-0.7-0.2-1.3-0.2-2s0.1-1.3,0.2-2h4.7c0.1,0.7,0.2,1.3,0.2,2S14.4,13.3,14.3,14z M14.6,19.6c0.6-1.1,1.1-2.3,1.4-3.6h2.9C18,17.7,16.4,18.9,14.6,19.6z M16.4,14c0.1-0.7,0.1-1.3,0.1-2s-0.1-1.3-0.1-2h3.4c0.2,0.6,0.3,1.3,0.3,2s-0.1,1.4-0.3,2H16.4z"></path></g>
|
||
|
<g id="launch"><path d="M19,19H5V5h7V3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2v-7h-2V19z M14,3v2h3.6l-9.8,9.8l1.4,1.4L19,6.4V10h2V3H14z"></path></g>
|
||
|
<g id="link"><path d="M8,13h8v-2H8V13z M3.9,12c0-2.3,1.8-4.1,4.1-4.1h3V6H8c-3.3,0-6,2.7-6,6s2.7,6,6,6h3v-1.9H8C5.7,16.1,3.9,14.3,3.9,12z M16,6h-3v1.9h3c2.3,0,4.1,1.8,4.1,4.1c0,2.3-1.8,4.1-4.1,4.1h-3V18h3c3.3,0,6-2.7,6-6S19.3,6,16,6z"></path></g>
|
||
|
<g id="list"><path d="M3,13h2v-2H3V13z M3,17h2v-2H3V17z M3,9h2V7H3V9z M7,13h14v-2H7V13z M7,17h14v-2H7V17z M7,7v2h14V7H7z"></path></g>
|
||
|
<g id="lock"><path d="M18,8h-1V6c0-2.8-2.2-5-5-5C9.2,1,7,3.2,7,6v2H6c-1.1,0-2,0.9-2,2v10c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V10C20,8.9,19.1,8,18,8z M12,17c-1.1,0-2-0.9-2-2s0.9-2,2-2c1.1,0,2,0.9,2,2S13.1,17,12,17z M15.1,8H8.9V6c0-1.7,1.4-3.1,3.1-3.1c1.7,0,3.1,1.4,3.1,3.1V8z"></path></g>
|
||
|
<g id="lock-open"><path d="M12,17c1.1,0,2-0.9,2-2s-0.9-2-2-2c-1.1,0-2,0.9-2,2S10.9,17,12,17z M18,8h-1V6c0-2.8-2.2-5-5-5C9.2,1,7,3.2,7,6h1.9c0-1.7,1.4-3.1,3.1-3.1c1.7,0,3.1,1.4,3.1,3.1v2H6c-1.1,0-2,0.9-2,2v10c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V10C20,8.9,19.1,8,18,8z M18,20H6V10h12V20z"></path></g>
|
||
|
<g id="lock-outline"><path d="M18,8h-1V6c0-2.8-2.2-5-5-5C9.2,1,7,3.2,7,6v2H6c-1.1,0-2,0.9-2,2v10c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V10C20,8.9,19.1,8,18,8z M12,2.9c1.7,0,3.1,1.4,3.1,3.1v2H9V6H8.9C8.9,4.3,10.3,2.9,12,2.9z M18,20H6V10h12V20z M12,17c1.1,0,2-0.9,2-2s-0.9-2-2-2c-1.1,0-2,0.9-2,2S10.9,17,12,17z"></path></g>
|
||
|
<g id="mail"><path d="M20,4H4C2.9,4,2,4.9,2,6l0,12c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V6C22,4.9,21.1,4,20,4z M20,8l-8,5L4,8V6l8,5l8-5V8z"></path></g>
|
||
|
<g id="markunread"><path d="M22,6l2-2l-2-2l-2,2l-2-2l-2,2l-2-2l-2,2l-2-2L8,4L6,2L4,4L2,2L0,4l2,2L0,8l2,2l-2,2l2,2l-2,2l2,2l-2,2l2,2l2-2l2,2l2-2l2,2l2-2l2,2l2-2l2,2l2-2l2,2l2-2l-2-2l2-2l-2-2l2-2l-2-2l2-2L22,6z M20,8l-8,5L4,8V6l8,5l8-5V8z"></path></g>
|
||
|
<g id="menu"><path d="M3,18h18v-2H3V18z M3,13h18v-2H3V13z M3,6v2h18V6H3z"></path></g>
|
||
|
<g id="more-horiz"><path d="M6,10c-1.1,0-2,0.9-2,2s0.9,2,2,2c1.1,0,2-0.9,2-2S7.1,10,6,10z M18,10c-1.1,0-2,0.9-2,2s0.9,2,2,2c1.1,0,2-0.9,2-2S19.1,10,18,10z M12,10c-1.1,0-2,0.9-2,2s0.9,2,2,2c1.1,0,2-0.9,2-2S13.1,10,12,10z"></path></g>
|
||
|
<g id="more-vert"><path d="M12,8c1.1,0,2-0.9,2-2s-0.9-2-2-2c-1.1,0-2,0.9-2,2S10.9,8,12,8z M12,10c-1.1,0-2,0.9-2,2s0.9,2,2,2c1.1,0,2-0.9,2-2S13.1,10,12,10z M12,16c-1.1,0-2,0.9-2,2s0.9,2,2,2c1.1,0,2-0.9,2-2S13.1,16,12,16z"></path></g>
|
||
|
<g id="polymer"><polygon points="19,4 15,4 7.1,16.6 4.5,12 9,4 5,4 0.5,12 5,20 9,20 16.9,7.4 19.5,12 15,20 19,20 23.5,12 "></polygon></g>
|
||
|
<g id="print"><path d="M19,8H5c-1.7,0-3,1.3-3,3v6h4v4h12v-4h4v-6C22,9.3,20.7,8,19,8z M16,19H8v-5h8V19z M19,12c-0.6,0-1-0.4-1-1s0.4-1,1-1c0.6,0,1,0.4,1,1S19.6,12,19,12z M18,3H6v4h12V3z"></path></g>
|
||
|
<g id="radio-button-off"><path d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10c5.5,0,10-4.5,10-10S17.5,2,12,2z M12,20c-4.4,0-8-3.6-8-8s3.6-8,8-8c4.4,0,8,3.6,8,8S16.4,20,12,20z"></path></g>
|
||
|
<g id="radio-button-on"><path d="M12,7c-2.8,0-5,2.2-5,5s2.2,5,5,5c2.8,0,5-2.2,5-5S14.8,7,12,7z M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10c5.5,0,10-4.5,10-10S17.5,2,12,2z M12,20c-4.4,0-8-3.6-8-8s3.6-8,8-8c4.4,0,8,3.6,8,8S16.4,20,12,20z"></path></g>
|
||
|
<g id="receipt"><path d="M18,17H6v-2h12V17z M18,13H6v-2h12V13z M18,9H6V7h12V9z M3,22l1.5-1.5L6,22l1.5-1.5L9,22l1.5-1.5L12,22l1.5-1.5L15,22l1.5-1.5L18,22l1.5-1.5L21,22V2l-1.5,1.5L18,2l-1.5,1.5L15,2l-1.5,1.5L12,2l-1.5,1.5L9,2L7.5,3.5L6,2L4.5,3.5L3,2V22z"></path></g>
|
||
|
<g id="refresh"><path d="M17.6,6.4C16.2,4.9,14.2,4,12,4c-4.4,0-8,3.6-8,8s3.6,8,8,8c3.7,0,6.8-2.6,7.7-6h-2.1c-0.8,2.3-3,4-5.6,4c-3.3,0-6-2.7-6-6s2.7-6,6-6c1.7,0,3.1,0.7,4.2,1.8L13,11h7V4L17.6,6.4z"></path></g>
|
||
|
<g id="reminder"><path d="M16.9,13c1.3-1.3,2.1-3,2.1-5c0-3.9-3.1-7-7-7C8.1,1,5,4.1,5,8c0,2,0.8,3.7,2.1,5l0,0l3.5,3.5L6,21.1l1.4,1.4L16.9,13z M15.5,11.5L15.5,11.5L12,15.1l-3.5-3.5l0,0l0,0C7.6,10.6,7,9.4,7,8c0-2.8,2.2-5,5-5c2.8,0,5,2.2,5,5C17,9.4,16.4,10.6,15.5,11.5L15.5,11.5z M13.4,19.3l3.2,3.2l1.4-1.4l-3.2-3.2L13.4,19.3z"></path></g>
|
||
|
<g id="remove"><path d="M19,13H5v-2h14V13z"></path></g>
|
||
|
<g id="remove-circle"><path d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10c5.5,0,10-4.5,10-10S17.5,2,12,2z M17,13H7v-2h10V13z"></path></g>
|
||
|
<g id="remove-circle-outline"><path d="M7,11v2h10v-2H7z M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10c5.5,0,10-4.5,10-10S17.5,2,12,2z M12,20c-4.4,0-8-3.6-8-8s3.6-8,8-8c4.4,0,8,3.6,8,8S16.4,20,12,20z"></path></g>
|
||
|
<g id="reply"><path d="M10,9V5l-7,7l7,7v-4.1c5,0,8.5,1.6,11,5.1C20,15,17,10,10,9z"></path></g>
|
||
|
<g id="reply-all"><path d="M7,8V5l-7,7l7,7v-3l-4-4L7,8z M13,9V5l-7,7l7,7v-4.1c5,0,8.5,1.6,11,5.1C23,15,20,10,13,9z"></path></g>
|
||
|
<g id="report"><path d="M15.7,3H8.3L3,8.3v7.5L8.3,21h7.5l5.3-5.3V8.3L15.7,3z M12,17.3c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3C13.3,16.7,12.7,17.3,12,17.3z M13,13h-2V7h2V13z"></path></g>
|
||
|
<g id="rotate-left"><path d="M7.1,8.5L5.7,7.1C4.8,8.3,4.2,9.6,4.1,11h2C6.2,10.1,6.6,9.3,7.1,8.5z M6.1,13h-2c0.2,1.4,0.7,2.7,1.6,3.9l1.4-1.4C6.6,14.7,6.2,13.9,6.1,13z M7.1,18.3c1.2,0.9,2.5,1.4,3.9,1.6v-2c-0.9-0.1-1.7-0.5-2.5-1L7.1,18.3z M13,4.1V1L8.5,5.5L13,10V6.1c2.8,0.5,5,2.9,5,5.9s-2.2,5.4-5,5.9v2c3.9-0.5,7-3.9,7-7.9S16.9,4.6,13,4.1z"></path></g>
|
||
|
<g id="rotate-right"><path d="M15.5,5.5L11,1v3.1C7.1,4.6,4,7.9,4,12s3.1,7.4,7,7.9v-2C8.2,17.4,6,15,6,12s2.2-5.4,5-5.9V10L15.5,5.5z M19.9,11c-0.2-1.4-0.7-2.7-1.6-3.9l-1.4,1.4c0.5,0.8,0.9,1.6,1,2.5H19.9z M13,17.9v2c1.4-0.2,2.7-0.7,3.9-1.6l-1.4-1.4C14.7,17.4,13.9,17.8,13,17.9z M16.9,15.5l1.4,1.4c0.9-1.2,1.5-2.5,1.6-3.9h-2C17.8,13.9,17.4,14.7,16.9,15.5z"></path></g>
|
||
|
<g id="save"><path d="M17,3H5C3.9,3,3,3.9,3,5l0,14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V7L17,3z M12,19c-1.7,0-3-1.3-3-3s1.3-3,3-3c1.7,0,3,1.3,3,3S13.7,19,12,19z M15,9H5V5h10V9z"></path></g>
|
||
|
<g id="schedule"><path fill-opacity="0.9" d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10c5.5,0,10-4.5,10-10S17.5,2,12,2z M12,20c-4.4,0-8-3.6-8-8s3.6-8,8-8c4.4,0,8,3.6,8,8S16.4,20,12,20z"></path><polygon fill-opacity="0.9" points="12.5,7 11,7 11,13 16.2,16.2 17,14.9 12.5,12.2 "></polygon></g>
|
||
|
<g id="search"><path d="M15.5,14h-0.8l-0.3-0.3c1-1.1,1.6-2.6,1.6-4.2C16,5.9,13.1,3,9.5,3C5.9,3,3,5.9,3,9.5S5.9,16,9.5,16c1.6,0,3.1-0.6,4.2-1.6l0.3,0.3v0.8l5,5l1.5-1.5L15.5,14z M9.5,14C7,14,5,12,5,9.5S7,5,9.5,5C12,5,14,7,14,9.5S12,14,9.5,14z"></path></g>
|
||
|
<g id="select-all"><path d="M3,5h2V3C3.9,3,3,3.9,3,5z M3,13h2v-2H3V13z M7,21h2v-2H7V21z M3,9h2V7H3V9z M13,3h-2v2h2V3z M19,3v2h2C21,3.9,20.1,3,19,3z M5,21v-2H3C3,20.1,3.9,21,5,21z M3,17h2v-2H3V17z M9,3H7v2h2V3z M11,21h2v-2h-2V21z M19,13h2v-2h-2V13z M19,21c1.1,0,2-0.9,2-2h-2V21z M19,9h2V7h-2V9z M19,17h2v-2h-2V17z M15,21h2v-2h-2V21z M15,5h2V3h-2V5z M7,17h10V7H7V17z M9,9h6v6H9V9z"></path></g>
|
||
|
<g id="send"><polygon points="2,21 23,12 2,3 2,10 17,12 2,14 "></polygon></g>
|
||
|
<g id="settings"><path d="M19.4,13c0-0.3,0.1-0.6,0.1-1s0-0.7-0.1-1l2.1-1.7c0.2-0.2,0.2-0.4,0.1-0.6l-2-3.5C19.5,5.1,19.3,5,19,5.1l-2.5,1c-0.5-0.4-1.1-0.7-1.7-1l-0.4-2.6C14.5,2.2,14.2,2,14,2h-4C9.8,2,9.5,2.2,9.5,2.4L9.1,5.1C8.5,5.3,8,5.7,7.4,6.1L5,5.1C4.7,5,4.5,5.1,4.3,5.3l-2,3.5C2.2,8.9,2.3,9.2,2.5,9.4L4.6,11c0,0.3-0.1,0.6-0.1,1s0,0.7,0.1,1l-2.1,1.7c-0.2,0.2-0.2,0.4-0.1,0.6l2,3.5C4.5,18.9,4.7,19,5,18.9l2.5-1c0.5,0.4,1.1,0.7,1.7,1l0.4,2.6c0,0.2,0.2,0.4,0.5,0.4h4c0.2,0,0.5-0.2,0.5-0.4l0.4-2.6c0.6-0.3,1.2-0.6,1.7-1l2.5,1c0.2,0.1,0.5,0,0.6-0.2l2-3.5c0.1-0.2,0.1-0.5-0.1-0.6L19.4,13z M12,15.5c-1.9,0-3.5-1.6-3.5-3.5s1.6-3.5,3.5-3.5s3.5,1.6,3.5,3.5S13.9,15.5,12,15.5z"></path></g>
|
||
|
<g id="settings-applications"><path d="M12,10c-1.1,0-2,0.9-2,2s0.9,2,2,2s2-0.9,2-2S13.1,10,12,10z M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M17.2,12c0,0.2,0,0.5,0,0.7l1.5,1.2c0.1,0.1,0.2,0.3,0.1,0.4l-1.4,2.4c-0.1,0.2-0.3,0.2-0.4,0.2l-1.7-0.7c-0.4,0.3-0.8,0.5-1.2,0.7l-0.3,1.9c0,0.2-0.2,0.3-0.3,0.3h-2.8c-0.2,0-0.3-0.1-0.3-0.3L10,16.9c-0.4-0.2-0.8-0.4-1.2-0.7l-1.7,0.7c-0.2,0.1-0.3,0-0.4-0.2l-1.4-2.4c-0.1-0.2,0-0.3,0.1-0.4l1.5-1.2c0-0.2,0-0.5,0-0.7s0-0.5,0-0.7l-1.5-1.2c-0.1-0.1-0.2-0.3-0.1-0.4l1.4-2.4c0.1-0.2,0.3-0.2,0.4-0.2l1.7,0.7C9.2,7.6,9.6,7.3,10,7.1l0.3-1.9c0-0.2,0.2-0.3,0.3-0.3h2.8c0.2,0,0.3,0.1,0.3,0.3L14,7.1c0.4,0.2,0.8,0.4,1.2,0.7l1.7-0.7c0.2-0.1,0.3,0,0.4,0.2l1.4,2.4c0.1,0.2,0,0.3-0.1,0.4l-1.5,1.2C17.2,11.5,17.2,11.8,17.2,12z"></path></g>
|
||
|
<g id="settings-bluetooth"><path d="M11,24h2v-2h-2V24z M7,24h2v-2H7V24z M15,24h2v-2h-2V24z M17.7,5.7L12,0h-1v7.6L6.4,3L5,4.4l5.6,5.6L5,15.6L6.4,17l4.6-4.6V20h1l5.7-5.7L13.4,10L17.7,5.7z M13,3.8l1.9,1.9L13,7.6V3.8z M14.9,14.3L13,16.2v-3.8L14.9,14.3z"></path></g>
|
||
|
<g id="settings-cell"><path d="M7,24h2v-2H7V24z M11,24h2v-2h-2V24z M15,24h2v-2h-2V24z M16,0L8,0C6.9,0,6,0.9,6,2v16c0,1.1,0.9,2,2,2h8c1.1,0,2-0.9,2-2V2C18,0.9,17.1,0,16,0z M16,16H8V4h8V16z"></path></g>
|
||
|
<g id="settings-phone"><path d="M13,9h-2v2h2V9z M17,9h-2v2h2V9z M20,15.5c-1.2,0-2.4-0.2-3.6-0.6c-0.3-0.1-0.7,0-1,0.2l-2.2,2.2c-2.8-1.4-5.1-3.8-6.6-6.6l2.2-2.2c0.3-0.3,0.4-0.7,0.2-1C8.7,6.4,8.5,5.2,8.5,4c0-0.6-0.4-1-1-1H4C3.4,3,3,3.4,3,4c0,9.4,7.6,17,17,17c0.6,0,1-0.4,1-1v-3.5C21,15.9,20.6,15.5,20,15.5z M19,9v2h2V9H19z"></path></g>
|
||
|
<g id="settings-power"><path d="M7,24h2v-2H7V24z M11,24h2v-2h-2V24z M13,2h-2v10h2V2z M16.6,4.4l-1.4,1.4C16.8,6.9,18,8.8,18,11c0,3.3-2.7,6-6,6c-3.3,0-6-2.7-6-6c0-2.2,1.2-4.1,2.9-5.1L7.4,4.4C5.4,5.9,4,8.3,4,11c0,4.4,3.6,8,8,8c4.4,0,8-3.6,8-8C20,8.3,18.6,5.9,16.6,4.4z M15,24h2v-2h-2V24z"></path></g>
|
||
|
<g id="settings-voice"><path d="M7,24h2v-2H7V24z M12,13c1.7,0,3-1.3,3-3l0-6c0-1.7-1.3-3-3-3c-1.7,0-3,1.3-3,3v6C9,11.7,10.3,13,12,13z M11,24h2v-2h-2V24z M15,24h2v-2h-2V24z M19,10h-1.7c0,3-2.5,5.1-5.3,5.1c-2.8,0-5.3-2.1-5.3-5.1H5c0,3.4,2.7,6.2,6,6.7V20h2v-3.3C16.3,16.2,19,13.4,19,10z"></path></g>
|
||
|
<g id="shopping-basket"><path d="M17.2,9l-4.4-6.6C12.6,2.2,12.3,2,12,2c-0.3,0-0.6,0.1-0.8,0.4L6.8,9H2c-0.6,0-1,0.4-1,1c0,0.1,0,0.2,0,0.3l2.5,9.3c0.2,0.8,1,1.5,1.9,1.5h13c0.9,0,1.7-0.6,1.9-1.5l2.5-9.3c0-0.1,0-0.2,0-0.3c0-0.6-0.4-1-1-1H17.2z M9,9l3-4.4L15,9H9z M12,17c-1.1,0-2-0.9-2-2s0.9-2,2-2c1.1,0,2,0.9,2,2S13.1,17,12,17z"></path></g>
|
||
|
<g id="shopping-cart"><path d="M7,18c-1.1,0-2,0.9-2,2s0.9,2,2,2c1.1,0,2-0.9,2-2S8.1,18,7,18z M1,2v2h2l3.6,7.6L5.2,14C5.1,14.3,5,14.7,5,15c0,1.1,0.9,2,2,2h12v-2H7.4c-0.1,0-0.2-0.1-0.2-0.2c0,0,0-0.1,0-0.1L8.1,13h7.4c0.8,0,1.4-0.4,1.7-1l3.6-6.5C21,5.3,21,5.2,21,5c0-0.6-0.4-1-1-1H5.2L4.3,2H1z M17,18c-1.1,0-2,0.9-2,2s0.9,2,2,2c1.1,0,2-0.9,2-2S18.1,18,17,18z"></path></g>
|
||
|
<g id="sort"><path d="M3,18h6v-2H3V18z M3,6v2h18V6H3z M3,13h12v-2H3V13z"></path></g>
|
||
|
<g id="star"><polygon points="12,17.273 18.18,21 16.545,13.971 22,9.244 14.809,8.627 12,2 9.191,8.627 2,9.244 7.455,13.971 5.82,21 "></polygon></g>
|
||
|
<g id="star-half"><path d="M22,9.744l-7.191-0.617L12,2.5L9.191,9.127L2,9.744v0l0,0l5.455,4.727L5.82,21.5L12,17.772l0,0l6.18,3.727l-1.635-7.029L22,9.744z M12,15.896V6.595l1.71,4.036l4.38,0.376l-3.322,2.878l0.996,4.281L12,15.896z"></path></g>
|
||
|
<g id="star-outline"><path d="M22,9.244l-7.191-0.617L12,2L9.191,8.627L2,9.244l5.455,4.727L5.82,21L12,17.272L18.18,21l-1.635-7.029L22,9.244z M12,15.396l-3.763,2.27l0.996-4.281L5.91,10.507l4.38-0.376L12,6.095l1.71,4.036l4.38,0.376l-3.322,2.878l0.996,4.281L12,15.396z"></path></g>
|
||
|
<g id="star-rate"><polygon points="12,14.3 15.7,17 14.3,12.6 18,10 13.5,10 12,5.5 10.5,10 6,10 9.7,12.6 8.3,17 "></polygon></g>
|
||
|
<g id="store"><path d="M20,4H4v2h16V4z M21,14v-2l-1-5H4l-1,5v2h1v6h10v-6h4v6h2v-6H21z M12,18H6v-4h6V18z"></path></g>
|
||
|
<g id="swap-driving-apps"><circle cx="6.5" cy="15.5" r="1.5"></circle><circle cx="17.5" cy="15.5" r="1.5"></circle><path d="M18.9,7c-0.2-0.6-0.8-1-1.4-1H16H6V4L3,7l2,2l1,1V8h11.7l1.3,4H3v9c0,0.6,0.4,1,1,1h1c0.6,0,1-0.4,1-1v-1h12v1c0,0.6,0.4,1,1,1h1c0.6,0,1-0.4,1-1v-8L18.9,7z M6.5,17C5.7,17,5,16.3,5,15.5S5.7,14,6.5,14C7.3,14,8,14.7,8,15.5S7.3,17,6.5,17z M17.5,17c-0.8,0-1.5-0.7-1.5-1.5s0.7-1.5,1.5-1.5c0.8,0,1.5,0.7,1.5,1.5S18.3,17,17.5,17z M16,0v2H8v2h8v2l3-3L16,0z"></path></g>
|
||
|
<g id="swap-horiz"><path d="M7,11l-4,4l4,4v-3h7v-2H7V11z M21,9l-4-4v3h-7v2h7v3L21,9z"></path></g>
|
||
|
<g id="swap-vert"><path d="M16,17v-7h-2v7h-3l4,4l4-4H16z M9,3L5,7h3v7h2V7h3L9,3z"></path></g>
|
||
|
<g id="swap-vert-circle"><path d="M12,2C6.5,2,2,6.5,2,12s4.5,10,10,10c5.5,0,10-4.5,10-10S17.5,2,12,2z M6.5,9L10,5.5L13.5,9H11v4H9V9H6.5z M17.5,15L14,18.5L10.5,15H13v-4h2v4H17.5z"></path></g>
|
||
|
<g id="tab"><path d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M19,19L5,19V5h7v4h7V19z"></path></g>
|
||
|
<g id="tab-unselected"><path d="M3,9h2V7H3V9z M3,13h2v-2H3V13z M3,5h2V3C3.9,3,3,3.9,3,5z M7,21h2v-2l-2,0V21z M3,17h2v-2H3V17z M5,21v-2H3C3,20.1,3.9,21,5,21z M19,3h-8v6h10V5C21,3.9,20.1,3,19,3z M19,17h2v-2h-2V17z M7,5h2V3H7V5z M19,21c1.1,0,2-0.9,2-2h-2V21z M19,13h2v-2h-2V13z M11,21h2v-2l-2,0V21z M15,21h2v-2l-2,0V21z"></path></g>
|
||
|
<g id="text-format"><path d="M5,17v2h14v-2H5z M9.5,12.8h5l0.9,2.2h2.1L12.8,4h-1.5L6.5,15h2.1L9.5,12.8z M12,6l1.9,5h-3.7L12,6z"></path></g>
|
||
|
<g id="theaters"><path d="M18,3v2h-2V3H8v2H6V3H4v18h2v-2h2v2h8v-2h2v2h2V3H18z M8,17H6v-2h2V17z M8,13H6v-2h2V13z M8,9H6V7h2V9z M18,17h-2v-2h2V17z M18,13h-2v-2h2V13z M18,9h-2V7h2V9z"></path></g>
|
||
|
<g id="thumb-down"><path d="M15,3H6C5.2,3,4.5,3.5,4.2,4.2l-3,7.1C1.1,11.5,1,11.7,1,12v1.9l0,0c0,0,0,0.1,0,0.1c0,1.1,0.9,2,2,2h6.3l-1,4.6c0,0.1,0,0.2,0,0.3c0,0.4,0.2,0.8,0.4,1.1L9.8,23l6.6-6.6c0.4-0.4,0.6-0.9,0.6-1.4V5C17,3.9,16.1,3,15,3z M19,3v12h4V3H19z"></path></g>
|
||
|
<g id="thumb-up"><path d="M1,21h4V9H1V21z M23,10c0-1.1-0.9-2-2-2h-6.3l1-4.6c0-0.1,0-0.2,0-0.3c0-0.4-0.2-0.8-0.4-1.1L14.2,1L7.6,7.6C7.2,7.9,7,8.4,7,9v10c0,1.1,0.9,2,2,2h9c0.8,0,1.5-0.5,1.8-1.2l3-7.1c0.1-0.2,0.1-0.5,0.1-0.7V10L23,10C23,10.1,23,10,23,10z"></path></g>
|
||
|
<g id="today"><path d="M19,3h-1V1h-2v2H8V1H6v2H5C3.9,3,3,3.9,3,5l0,14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M19,19H5V8h14V19z"></path><rect x="7" y="10" width="5" height="5"></rect></g>
|
||
|
<g id="translate"><path d="M3,17.2V21h3.8L17.8,9.9l-3.8-3.8L3,17.2z M20.7,7c0.4-0.4,0.4-1,0-1.4l-2.3-2.3c-0.4-0.4-1-0.4-1.4,0l-1.8,1.8l3.8,3.8L20.7,7z M12,19l-2,2h13v-2H12z"></path></g>
|
||
|
<g id="undo"><path d="M12,5V1.5l-5,5l5,5V7c3.3,0,6,2.7,6,6s-2.7,6-6,6c-3.3,0-6-2.7-6-6H4c0,4.4,3.6,8,8,8c4.4,0,8-3.6,8-8S16.4,5,12,5z"></path></g>
|
||
|
<g id="unfold-less"><path d="M7.4,18.6L8.8,20l3.2-3.2l3.2,3.2l1.4-1.4L12,14L7.4,18.6z M16.6,5.4L15.2,4L12,7.2L8.8,4L7.4,5.4L12,10L16.6,5.4z"></path></g>
|
||
|
<g id="unfold-more"><path d="M12,5.8L15.2,9l1.4-1.4L12,3L7.4,7.6L8.8,9L12,5.8z M12,18.2L8.8,15l-1.4,1.4L12,21l4.6-4.6L15.2,15L12,18.2z"></path></g>
|
||
|
<g id="view-array"><path d="M4,18h3V5H4V18z M18,5v13h3V5H18z M8,18h9V5H8V18z"></path></g>
|
||
|
<g id="view-column"><path d="M10,18h5V5h-5V18z M4,18h5V5H4V18z M16,5v13h5V5H16z"></path></g>
|
||
|
<g id="view-headline"><path d="M4,15h17v-2H4V15z M4,19h17v-2H4V19z M4,11h17V9H4V11z M4,5v2h17V5H4z"></path></g>
|
||
|
<g id="view-list"><path d="M4,14h4v-4H4V14z M4,19h4v-4H4V19z M4,9h4V5H4V9z M9,14h12v-4H9V14z M9,19h12v-4H9V19z M9,5v4h12V5H9z"></path></g>
|
||
|
<g id="view-module"><path d="M4,11h5V5H4V11z M4,18h5v-6H4V18z M10,18h5v-6h-5V18z M16,18h5v-6h-5V18z M10,11h5V5h-5V11z M16,5v6h5V5H16z"></path></g>
|
||
|
<g id="view-quilt"><path d="M10,18h5v-6h-5V18z M4,18h5V5H4V18z M16,18h5v-6h-5V18z M10,5v6h11V5H10z"></path></g>
|
||
|
<g id="view-stream"><path d="M4,18h17v-6H4V18z M4,5v6h17V5H4z"></path></g>
|
||
|
<g id="visibility"><path d="M12,4.5C7,4.5,2.7,7.6,1,12c1.7,4.4,6,7.5,11,7.5c5,0,9.3-3.1,11-7.5C21.3,7.6,17,4.5,12,4.5z M12,17c-2.8,0-5-2.2-5-5s2.2-5,5-5c2.8,0,5,2.2,5,5S14.8,17,12,17z M12,9c-1.7,0-3,1.3-3,3s1.3,3,3,3c1.7,0,3-1.3,3-3S13.7,9,12,9z"></path></g>
|
||
|
<g id="visibility-off"><path d="M12,7c2.8,0,5,2.2,5,5c0,0.6-0.1,1.3-0.4,1.8l2.9,2.9c1.5-1.3,2.7-2.9,3.4-4.7c-1.7-4.4-6-7.5-11-7.5c-1.4,0-2.7,0.3-4,0.7l2.2,2.2C10.7,7.1,11.4,7,12,7z M2,4.3l2.3,2.3L4.7,7c-1.7,1.3-3,3-3.7,5c1.7,4.4,6,7.5,11,7.5c1.5,0,3-0.3,4.4-0.8l0.4,0.4l2.9,2.9l1.3-1.3L3.3,3L2,4.3z M7.5,9.8l1.5,1.5C9,11.6,9,11.8,9,12c0,1.7,1.3,3,3,3c0.2,0,0.4,0,0.7-0.1l1.5,1.5C13.5,16.8,12.8,17,12,17c-2.8,0-5-2.2-5-5C7,11.2,7.2,10.5,7.5,9.8z M11.8,9l3.1,3.1c0-0.1,0-0.1,0-0.2c0-1.7-1.3-3-3-3C11.9,9,11.9,9,11.8,9z"></path></g>
|
||
|
<g id="warning"><path d="M1,21h22L12,2L1,21z M13,18h-2v-2h2V18z M13,14h-2v-4h2V14z"></path></g>
|
||
|
<g id="work"><path d="M20,6h-4V4l-2-2h-4L8,4v2H4C2.9,6,2,6.9,2,8l0,11c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V8C22,6.9,21.1,6,20,6z M14,6h-4V4h4V6z"></path></g>
|
||
|
</defs></svg>
|
||
|
</core-iconset-svg>
|
||
|
|
||
|
<!-- import core-icon for convenience
|
||
|
TODO(sorvell): we'd rather do this in core-iconset but we can't until
|
||
|
crbug.com/373461 is addressed
|
||
|
-->
|
||
|
<!--
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
-->
|
||
|
<!--
|
||
|
|
||
|
The `core-icon` element displays an icon using CSS background image. By default an icon renders as 24px square.
|
||
|
|
||
|
Example using src:
|
||
|
|
||
|
<core-icon src="star.png"></core-icon>
|
||
|
|
||
|
Example setting size to 32px x 32px:
|
||
|
|
||
|
<core-icon src="big_star.png" size="32"></core-icon>
|
||
|
|
||
|
Example using icon from default iconset:
|
||
|
|
||
|
<core-icon icon="menu"></core-icon>
|
||
|
|
||
|
Example using icon `cherry` from custom iconset `fruit`:
|
||
|
|
||
|
<core-icon icon="fruit:cherry"></core-icon>
|
||
|
|
||
|
See [core-iconset](#core-iconset) and [core-iconset-svg](#core-iconset-svg) for more information about
|
||
|
how to use a custom iconset.
|
||
|
|
||
|
See [core-icons](#core-icons) for the default set of icons. To use the default set of icons you'll need to include an import for `core-icons.html`.
|
||
|
|
||
|
@group Polymer Core Elements
|
||
|
@element core-icon
|
||
|
@homepage polymer.github.io
|
||
|
-->
|
||
|
|
||
|
|
||
|
<style shim-shadowdom="">/* Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt */
|
||
|
|
||
|
html /deep/ core-icon {
|
||
|
display: inline-block;
|
||
|
vertical-align: middle;
|
||
|
background-repeat: no-repeat;
|
||
|
}
|
||
|
|
||
|
html /deep/ core-icon[size=""] {
|
||
|
position: relative;
|
||
|
}
|
||
|
|
||
|
html /deep/ core-icon[size=""] > svg {
|
||
|
position: absolute;
|
||
|
top: 0;
|
||
|
right: 0;
|
||
|
bottom: 0;
|
||
|
left: 0;
|
||
|
}
|
||
|
</style>
|
||
|
|
||
|
<polymer-element name="core-icon" attributes="src size icon" assetpath="../core-icon/">
|
||
|
<script>
|
||
|
(function() {
|
||
|
|
||
|
// mono-state
|
||
|
var meta;
|
||
|
|
||
|
Polymer('core-icon', {
|
||
|
|
||
|
/**
|
||
|
* The URL of an image for the icon. If the src property is specified,
|
||
|
* the icon property should not be.
|
||
|
*
|
||
|
* @attribute src
|
||
|
* @type string
|
||
|
* @default ''
|
||
|
*/
|
||
|
src: '',
|
||
|
|
||
|
/**
|
||
|
* Specifies the size of the icon in pixel units.
|
||
|
*
|
||
|
* @attribute size
|
||
|
* @type string
|
||
|
* @default 24
|
||
|
*/
|
||
|
size: 24,
|
||
|
|
||
|
/**
|
||
|
* Specifies the icon name or index in the set of icons available in
|
||
|
* the icon's icon set. If the icon property is specified,
|
||
|
* the src property should not be.
|
||
|
*
|
||
|
* @attribute icon
|
||
|
* @type string
|
||
|
* @default ''
|
||
|
*/
|
||
|
icon: '',
|
||
|
|
||
|
observe: {
|
||
|
'size icon': 'updateIcon'
|
||
|
},
|
||
|
|
||
|
defaultIconset: 'icons',
|
||
|
|
||
|
ready: function() {
|
||
|
if (!meta) {
|
||
|
meta = document.createElement('core-iconset');
|
||
|
}
|
||
|
this.updateIcon();
|
||
|
},
|
||
|
|
||
|
srcChanged: function() {
|
||
|
this.style.backgroundImage = 'url(' + this.src + ')';
|
||
|
this.style.backgroundPosition = 'center';
|
||
|
this.style.backgroundSize = this.size + 'px ' + this.size + 'px';
|
||
|
},
|
||
|
|
||
|
getIconset: function(name) {
|
||
|
return meta.byId(name || this.defaultIconset);
|
||
|
},
|
||
|
|
||
|
updateIcon: function() {
|
||
|
if (this.size) {
|
||
|
this.style.width = this.style.height = this.size + 'px';
|
||
|
}
|
||
|
if (this.icon) {
|
||
|
var parts = String(this.icon).split(':');
|
||
|
var icon = parts.pop();
|
||
|
if (icon) {
|
||
|
var set = this.getIconset(parts.pop());
|
||
|
if (set) {
|
||
|
set.applyIcon(this, icon, this.size / set.iconSize);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
})();
|
||
|
</script>
|
||
|
|
||
|
</polymer-element>
|
||
|
|
||
|
|
||
|
<!--
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
-->
|
||
|
|
||
|
<!--
|
||
|
`core-icon-button` is an icon with button behaviors.
|
||
|
|
||
|
<core-icon-button src="star.png"></core-icon-button>
|
||
|
|
||
|
`core-icon-button` includes a default icon set. Use `icon` to specify
|
||
|
which icon from the icon set to use.
|
||
|
|
||
|
<core-icon-button icon="menu"></core-icon-button>
|
||
|
|
||
|
See [`core-iconset`](#core-iconset) for more information about
|
||
|
how to use a custom icon set.
|
||
|
|
||
|
@group Polymer Core Elements
|
||
|
@element core-icon-button
|
||
|
@homepage github.io
|
||
|
-->
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<polymer-element name="core-icon-button" attributes="src icon active" assetpath="../core-icon-button/">
|
||
|
|
||
|
<template>
|
||
|
|
||
|
<style>/*
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
|
||
|
*/
|
||
|
|
||
|
:host {
|
||
|
display: inline-block;
|
||
|
box-sizing: border-box;
|
||
|
-moz-box-sizing: border-box;
|
||
|
width: 38px;
|
||
|
height: 38px;
|
||
|
background-image: none;
|
||
|
border-radius: 2px;
|
||
|
padding: 7px;
|
||
|
margin: 2px;
|
||
|
vertical-align: middle;
|
||
|
font-size: 1rem;
|
||
|
cursor: pointer;
|
||
|
}
|
||
|
|
||
|
:host([disabled]) {
|
||
|
opacity: 0.6;
|
||
|
pointer-events: none;
|
||
|
}
|
||
|
|
||
|
:host(.outline) {
|
||
|
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
|
||
|
}
|
||
|
|
||
|
:host(:hover:not([disabled])) {
|
||
|
box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.12), 0 0 0 1px rgba(0, 0, 0, 0.1);
|
||
|
}
|
||
|
|
||
|
:host(.selected:not([disabled])) {
|
||
|
background-color: rgba(0, 0, 0, 0.05);
|
||
|
box-shadow: inset 0 1px 0 0 rgba(0, 0, 0, 0.05), 0 0 0 1px rgba(0, 0, 0, 0.12);
|
||
|
}
|
||
|
|
||
|
:host(:active:not([disabled]), .selected:active:not([disabled])) {
|
||
|
background-color: rgba(0, 0, 0, 0.05);
|
||
|
box-shadow: inset 0 1px 0 0 rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.12);
|
||
|
}
|
||
|
|
||
|
:host(.core-dark-theme.outline) {
|
||
|
background-color: rgba(200, 200, 200, 0.05);
|
||
|
box-shadow: 0 0 0 1px rgba(200, 200, 200, 0.1);
|
||
|
}
|
||
|
|
||
|
:host(.core-dark-theme:hover) {
|
||
|
background-color: rgba(200, 200, 200, 0.05);
|
||
|
box-shadow: 0 1px 0 0 rgba(200, 200, 200, 0.12), 0 0 0 1px rgba(200, 200, 200, 0.1);
|
||
|
}
|
||
|
|
||
|
:host(.core-dark-theme.selected) {
|
||
|
background-color: rgba(220, 220, 220, 0.05);
|
||
|
box-shadow: inset 0 1px 0 0 rgba(200, 200, 200, 0.05), 0 0 0 1px rgba(200, 200, 200, 0.12);
|
||
|
}
|
||
|
|
||
|
:host(.core-dark-theme:active, .core-dark-theme.selected:active) {
|
||
|
background-color: rgba(200, 200, 200, 0.05);
|
||
|
box-shadow: inset 0 1px 0 0 rgba(200, 200, 200, 0.1), 0 0 0 1px rgba(200, 200, 200, 0.12);
|
||
|
}
|
||
|
|
||
|
core-icon {
|
||
|
pointer-events: none;
|
||
|
}
|
||
|
</style>
|
||
|
|
||
|
<core-icon src="{{src}}" icon="{{icon}}"><content></content></core-icon>
|
||
|
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
|
||
|
Polymer('core-icon-button', {
|
||
|
|
||
|
/**
|
||
|
* The URL of an image for the icon. Should not use `icon` property
|
||
|
* if you are using this property.
|
||
|
*
|
||
|
* @attribute src
|
||
|
* @type string
|
||
|
* @default ''
|
||
|
*/
|
||
|
src: '',
|
||
|
|
||
|
/**
|
||
|
* If true, border is placed around the button to indicate it's
|
||
|
* active state.
|
||
|
*
|
||
|
* @attribute active
|
||
|
* @type boolean
|
||
|
* @default false
|
||
|
*/
|
||
|
active: false,
|
||
|
|
||
|
/**
|
||
|
* Specifies the icon name or index in the set of icons available in
|
||
|
* the icon set. Should not use `src` property if you are using this
|
||
|
* property.
|
||
|
*
|
||
|
* @attribute icon
|
||
|
* @type string
|
||
|
* @default ''
|
||
|
*/
|
||
|
icon: '',
|
||
|
|
||
|
activeChanged: function() {
|
||
|
this.classList.toggle('selected', this.active);
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
</script>
|
||
|
|
||
|
</polymer-element>
|
||
|
|
||
|
<!--
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
-->
|
||
|
|
||
|
<!--
|
||
|
`core-toolbar` is a horizontal bar containing elements that can be used for
|
||
|
label, navigation, search and actions.
|
||
|
|
||
|
<core-toolbar>
|
||
|
<core-icon-button icon="menu" on-tap="{{menuAction}}"></core-icon-button>
|
||
|
<div flex>Title</div>
|
||
|
<core-icon-button icon="more" on-tap="{{moreAction}}"></core-icon-button>
|
||
|
</core-toolbar>
|
||
|
|
||
|
`core-toolbar` has a standard height, but can made be taller by setting `tall`
|
||
|
class on the `core-toolbar`. This will make the toolbar 3x the normal height.
|
||
|
|
||
|
<core-toolbar class="tall">
|
||
|
<core-icon-button icon="menu"></core-icon-button>
|
||
|
</core-toolbar>
|
||
|
|
||
|
Apply `medium-tall` class to make the toolbar medium tall. This will make the
|
||
|
toolbar 2x the normal height.
|
||
|
|
||
|
<core-toolbar class="medium-tall">
|
||
|
<core-icon-button icon="menu"></core-icon-button>
|
||
|
</core-toolbar>
|
||
|
|
||
|
When taller, elements can pin to either the top (default), middle or bottom.
|
||
|
|
||
|
<core-toolbar class="tall">
|
||
|
<core-icon-button icon="menu"></core-icon-button>
|
||
|
<div class="middle indent">Middle Title</div>
|
||
|
<div class="bottom indent">Bottom Title</div>
|
||
|
</core-toolbar>
|
||
|
|
||
|
To make an element completely fit at the bottom of the toolbar, use `fit` along
|
||
|
with `bottom`.
|
||
|
|
||
|
<core-toolbar class="tall">
|
||
|
<div id="progressBar" class="bottom fit"></div>
|
||
|
</core-toolbar>
|
||
|
|
||
|
@group Polymer Core Elements
|
||
|
@element core-toolbar
|
||
|
@homepage github.io
|
||
|
-->
|
||
|
|
||
|
|
||
|
|
||
|
<polymer-element name="core-toolbar" noscript="" assetpath="../core-toolbar/">
|
||
|
<template>
|
||
|
|
||
|
<style>/*
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
*/
|
||
|
|
||
|
:host {
|
||
|
/* technical */
|
||
|
display: block;
|
||
|
position: relative;
|
||
|
box-sizing: border-box;
|
||
|
-moz-box-sizing: border-box;
|
||
|
/* size */
|
||
|
height: 64px;
|
||
|
/* typography */
|
||
|
font-size: 1.3em;
|
||
|
/* background */
|
||
|
background-color: #CFD8DC;
|
||
|
}
|
||
|
|
||
|
:host(.animate) {
|
||
|
/* transition */
|
||
|
transition: height 0.18s ease-in;
|
||
|
}
|
||
|
|
||
|
:host(.medium-tall) {
|
||
|
height: 128px;
|
||
|
}
|
||
|
|
||
|
:host(.tall) {
|
||
|
height: 192px;
|
||
|
}
|
||
|
|
||
|
.toolbar-tools {
|
||
|
height: 64px;
|
||
|
padding: 0 8px;
|
||
|
pointer-events: none;
|
||
|
}
|
||
|
|
||
|
/* narrow layout */
|
||
|
:host(.narrow) {
|
||
|
height: 56px;
|
||
|
}
|
||
|
|
||
|
:host(.narrow.medium-tall) {
|
||
|
height: 112px;
|
||
|
}
|
||
|
|
||
|
:host(.narrow.tall) {
|
||
|
height: 168px;
|
||
|
}
|
||
|
|
||
|
:host(.narrow) .toolbar-tools {
|
||
|
height: 56px;
|
||
|
padding: 0;
|
||
|
}
|
||
|
|
||
|
/* middle bar */
|
||
|
#middleBar {
|
||
|
position: absolute;
|
||
|
top: 0;
|
||
|
right: 0;
|
||
|
left: 0;
|
||
|
}
|
||
|
|
||
|
:host(.tall, .medium-tall) #middleBar {
|
||
|
-webkit-transform: translateY(100%);
|
||
|
transform: translateY(100%);
|
||
|
}
|
||
|
|
||
|
/* bottom bar */
|
||
|
#bottomBar {
|
||
|
position: absolute;
|
||
|
right: 0;
|
||
|
bottom: 0;
|
||
|
left: 0;
|
||
|
}
|
||
|
|
||
|
/* shows bottom bar only when in normal height (!tall && !medium-tall) */
|
||
|
:host(.animate.no-overlap) > #topBar,
|
||
|
:host(.animate.no-overlap) > #middleBar {
|
||
|
transition: -webkit-transform 0.18s ease-in;
|
||
|
transition: transform 0.18s ease-in;
|
||
|
}
|
||
|
|
||
|
:host(.no-overlap:not(.medium-tall):not(.tall)) > #topBar {
|
||
|
-webkit-transform: translateY(-100%);
|
||
|
transform: translateY(-100%);
|
||
|
}
|
||
|
|
||
|
:host(.no-overlap:not(.medium-tall):not(.tall)) > #middleBar {
|
||
|
-webkit-transform: translateY(-200%);
|
||
|
transform: translateY(-200%);
|
||
|
}
|
||
|
|
||
|
/* make elements (e.g. buttons) respond to mouse/touch events */
|
||
|
polyfill-next-selector { content: '.toolbar-tools > *'; }
|
||
|
::content > * {
|
||
|
pointer-events: auto;
|
||
|
}
|
||
|
|
||
|
/* elements spacing */
|
||
|
polyfill-next-selector { content: '.toolbar-tools > *'; }
|
||
|
::content > * {
|
||
|
margin: 0px 8px;
|
||
|
}
|
||
|
|
||
|
/* misc helpers */
|
||
|
polyfill-next-selector { content: '.toolbar-tools > .fit'; }
|
||
|
::content > .fit {
|
||
|
position: absolute;
|
||
|
top: auto;
|
||
|
right: 0;
|
||
|
bottom: 0;
|
||
|
left: 0;
|
||
|
width: auto;
|
||
|
margin: 0;
|
||
|
}
|
||
|
|
||
|
polyfill-next-selector { content: ':host .indent'; }
|
||
|
::content > .indent {
|
||
|
margin-left: 60px;
|
||
|
}
|
||
|
</style>
|
||
|
|
||
|
<div id="bottomBar" class="toolbar-tools" center="" horizontal="" layout="">
|
||
|
<content select=".bottom"></content>
|
||
|
</div>
|
||
|
|
||
|
<div id="middleBar" class="toolbar-tools" center="" horizontal="" layout="">
|
||
|
<content select=".middle"></content>
|
||
|
</div>
|
||
|
|
||
|
<div id="topBar" class="toolbar-tools" center="" horizontal="" layout="">
|
||
|
<content></content>
|
||
|
</div>
|
||
|
|
||
|
</template>
|
||
|
</polymer-element>
|
||
|
|
||
|
<!--
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
-->
|
||
|
|
||
|
<!--
|
||
|
`core-header-panel` contains a header section and a content panel section.
|
||
|
|
||
|
__Important:__ The `core-header-panel` will not display if its parent does not have a height.
|
||
|
|
||
|
Using [layout attributes](http://www.polymer-project.org/docs/polymer/layout-attrs.html), you can easily make the `core-header-panel` fill the screen
|
||
|
|
||
|
<body fullbleed layout vertical>
|
||
|
<core-header-panel flex>
|
||
|
<core-toolbar>
|
||
|
<div>Hello World!</div>
|
||
|
</core-toolbar>
|
||
|
</core-header-panel>
|
||
|
</body>
|
||
|
|
||
|
or, if you would prefer to do it in CSS, just give `html`, `body`, and `core-header-panel` a height of 100%:
|
||
|
|
||
|
html, body {
|
||
|
height: 100%;
|
||
|
margin: 0;
|
||
|
}
|
||
|
core-header-panel {
|
||
|
height: 100%;
|
||
|
}
|
||
|
|
||
|
Special
|
||
|
support is provided for scrolling modes when one uses a core-toolbar or equivalent
|
||
|
for the header section.
|
||
|
|
||
|
Example:
|
||
|
|
||
|
<core-header-panel>
|
||
|
<core-toolbar>Header</core-toolbar>
|
||
|
<div>Content goes here...</div>
|
||
|
</core-header-panel>
|
||
|
|
||
|
If you want to use other than `core-toolbar` for the header, add
|
||
|
`core-header` class to that element.
|
||
|
|
||
|
Example:
|
||
|
|
||
|
<core-header-panel>
|
||
|
<div class="core-header">Header</div>
|
||
|
<div>Content goes here...</div>
|
||
|
</core-header-panel>
|
||
|
|
||
|
Use `mode` to control the header and scrolling behavior.
|
||
|
|
||
|
@group Polymer Core Elements
|
||
|
@element core-header-panel
|
||
|
@homepage github.io
|
||
|
-->
|
||
|
|
||
|
|
||
|
|
||
|
<polymer-element name="core-header-panel" assetpath="../core-header-panel/">
|
||
|
<template>
|
||
|
|
||
|
<style>/*
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
*/
|
||
|
|
||
|
:host {
|
||
|
display: block;
|
||
|
position: relative;
|
||
|
}
|
||
|
|
||
|
#outerContainer {
|
||
|
position: absolute;
|
||
|
top: 0;
|
||
|
right: 0;
|
||
|
bottom: 0;
|
||
|
left: 0;
|
||
|
overflow-y: auto;
|
||
|
overflow-x: hidden;
|
||
|
-webkit-overflow-scrolling: touch;
|
||
|
}
|
||
|
|
||
|
#mainPanel {
|
||
|
position: relative;
|
||
|
}
|
||
|
|
||
|
#mainContainer {
|
||
|
position: relative;
|
||
|
overflow-y: auto;
|
||
|
overflow-x: hidden;
|
||
|
-webkit-overflow-scrolling: touch;
|
||
|
}
|
||
|
|
||
|
#dropShadow {
|
||
|
position: absolute;
|
||
|
top: 0;
|
||
|
left: 0;
|
||
|
right: 0;
|
||
|
height: 6px;
|
||
|
box-shadow: inset 0px 5px 6px -3px rgba(0, 0, 0, 0.4);
|
||
|
}
|
||
|
|
||
|
#dropShadow.hidden {
|
||
|
display: none;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
mode: scroll
|
||
|
*/
|
||
|
:host([mode=scroll]) #mainContainer {
|
||
|
overflow: visible;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
mode: cover
|
||
|
*/
|
||
|
:host([mode=cover]) #mainPanel {
|
||
|
position: static;
|
||
|
}
|
||
|
|
||
|
:host([mode=cover]) #mainContainer {
|
||
|
position: absolute;
|
||
|
top: 0;
|
||
|
right: 0;
|
||
|
bottom: 0;
|
||
|
left: 0;
|
||
|
}
|
||
|
|
||
|
:host([mode=cover]) #dropShadow {
|
||
|
position: static;
|
||
|
width: 100%;
|
||
|
}
|
||
|
</style>
|
||
|
|
||
|
<div id="outerContainer" on-scroll="{{scroll}}" vertical="" layout="">
|
||
|
|
||
|
<content id="headerContent" select="core-toolbar, .core-header"></content>
|
||
|
|
||
|
<div id="mainPanel" flex="" vertical="" layout="">
|
||
|
|
||
|
<div id="mainContainer" flex?="{{mode !== 'cover'}}" on-scroll="{{scroll}}">
|
||
|
<content id="mainContent" select="*"></content>
|
||
|
</div>
|
||
|
|
||
|
<div id="dropShadow"></div>
|
||
|
|
||
|
</div>
|
||
|
|
||
|
</div>
|
||
|
|
||
|
</template>
|
||
|
<script>
|
||
|
|
||
|
Polymer('core-header-panel', {
|
||
|
|
||
|
publish: {
|
||
|
/**
|
||
|
* Controls header and scrolling behavior. Options are
|
||
|
* `standard`, `seamed`, `waterfall`, `waterfall-tall`,
|
||
|
* `waterfall-medium-tall`, `scroll` and `cover`.
|
||
|
* Default is `standard`.
|
||
|
*
|
||
|
* `standard`: The header is a step above the panel. The header will consume the
|
||
|
* panel at the point of entry, preventing it from passing through to the
|
||
|
* opposite side.
|
||
|
*
|
||
|
* `seamed`: The header is presented as seamed with the panel.
|
||
|
*
|
||
|
* `waterfall`: Similar to standard mode, but header is initially presented as
|
||
|
* seamed with panel, but then separates to form the step.
|
||
|
*
|
||
|
* `waterfall-tall`: The header is initially taller (`tall` class is added to
|
||
|
* the header). As the user scrolls, the header separates (forming an edge)
|
||
|
* while condensing (`tall` class is removed from the header).
|
||
|
*
|
||
|
* `scroll`: The header keeps its seam with the panel, and is pushed off screen.
|
||
|
*
|
||
|
* `cover`: The panel covers the whole `core-header-panel` including the
|
||
|
* header. This allows user to style the panel in such a way that the panel is
|
||
|
* partially covering the header.
|
||
|
*
|
||
|
* <style>
|
||
|
* core-header-panel[mode=cover]::shadow #mainContainer {
|
||
|
* left: 80px;
|
||
|
* }
|
||
|
* .content {
|
||
|
* margin: 60px 60px 60px 0;
|
||
|
* }
|
||
|
* </style>
|
||
|
*
|
||
|
* <core-header-panel mode="cover">
|
||
|
* <core-appbar class="tall">
|
||
|
* <core-icon-button icon="menu"></core-icon-button>
|
||
|
* </core-appbar>
|
||
|
* <div class="content"></div>
|
||
|
* </core-header-panel>
|
||
|
*
|
||
|
* @attribute mode
|
||
|
* @type string
|
||
|
* @default ''
|
||
|
*/
|
||
|
mode: {value: '', reflect: true},
|
||
|
|
||
|
/**
|
||
|
* The class used in waterfall-tall mode. Change this if the header
|
||
|
* accepts a different class for toggling height, e.g. "medium-tall"
|
||
|
*
|
||
|
* @attribute tallClass
|
||
|
* @type string
|
||
|
* @default 'tall'
|
||
|
*/
|
||
|
tallClass: 'tall',
|
||
|
|
||
|
/**
|
||
|
* If true, the drop-shadow is always shown no matter what mode is set to.
|
||
|
*
|
||
|
* @attribute shadow
|
||
|
* @type boolean
|
||
|
* @default false
|
||
|
*/
|
||
|
shadow: false,
|
||
|
},
|
||
|
|
||
|
domReady: function() {
|
||
|
this.async('scroll');
|
||
|
},
|
||
|
|
||
|
modeChanged: function() {
|
||
|
this.scroll();
|
||
|
},
|
||
|
|
||
|
get header() {
|
||
|
return this.$.headerContent.getDistributedNodes()[0];
|
||
|
},
|
||
|
|
||
|
scroll: function() {
|
||
|
var shadowMode = {'waterfall': 1, 'waterfall-tall': 1};
|
||
|
var noShadow = {'seamed': 1, 'cover': 1, 'scroll': 1};
|
||
|
var tallMode = {'waterfall-tall': 1};
|
||
|
|
||
|
var main = this.$.mainContainer;
|
||
|
var header = this.header;
|
||
|
|
||
|
var sTop = main.scrollTop;
|
||
|
var atTop = sTop === 0;
|
||
|
|
||
|
if (header) {
|
||
|
this.$.dropShadow.classList.toggle('hidden', !this.shadow &&
|
||
|
(atTop && shadowMode[this.mode] || noShadow[this.mode]));
|
||
|
|
||
|
if (tallMode[this.mode]) {
|
||
|
header.classList.toggle(this.tallClass, atTop);
|
||
|
}
|
||
|
|
||
|
header.classList.toggle('animate', tallMode[this.mode]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
</script>
|
||
|
</polymer-element>
|
||
|
|
||
|
<!--
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
-->
|
||
|
|
||
|
|
||
|
<script>/**
|
||
|
* marked - a markdown parser
|
||
|
* Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
|
||
|
* https://github.com/chjj/marked
|
||
|
*/
|
||
|
|
||
|
;(function() {
|
||
|
|
||
|
/**
|
||
|
* Block-Level Grammar
|
||
|
*/
|
||
|
|
||
|
var block = {
|
||
|
newline: /^\n+/,
|
||
|
code: /^( {4}[^\n]+\n*)+/,
|
||
|
fences: noop,
|
||
|
hr: /^( *[-*_]){3,} *(?:\n+|$)/,
|
||
|
heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
|
||
|
nptable: noop,
|
||
|
lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
|
||
|
blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
|
||
|
list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
|
||
|
html: /^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/,
|
||
|
def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
|
||
|
table: noop,
|
||
|
paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
|
||
|
text: /^[^\n]+/
|
||
|
};
|
||
|
|
||
|
block.bullet = /(?:[*+-]|\d+\.)/;
|
||
|
block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
|
||
|
block.item = replace(block.item, 'gm')
|
||
|
(/bull/g, block.bullet)
|
||
|
();
|
||
|
|
||
|
block.list = replace(block.list)
|
||
|
(/bull/g, block.bullet)
|
||
|
('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
|
||
|
('def', '\\n+(?=' + block.def.source + ')')
|
||
|
();
|
||
|
|
||
|
block.blockquote = replace(block.blockquote)
|
||
|
('def', block.def)
|
||
|
();
|
||
|
|
||
|
block._tag = '(?!(?:'
|
||
|
+ 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
|
||
|
+ '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
|
||
|
+ '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b';
|
||
|
|
||
|
block.html = replace(block.html)
|
||
|
('comment', /<!--[\s\S]*?-->/)
|
||
|
('closed', /<(tag)[\s\S]+?<\/\1>/)
|
||
|
('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
|
||
|
(/tag/g, block._tag)
|
||
|
();
|
||
|
|
||
|
block.paragraph = replace(block.paragraph)
|
||
|
('hr', block.hr)
|
||
|
('heading', block.heading)
|
||
|
('lheading', block.lheading)
|
||
|
('blockquote', block.blockquote)
|
||
|
('tag', '<' + block._tag)
|
||
|
('def', block.def)
|
||
|
();
|
||
|
|
||
|
/**
|
||
|
* Normal Block Grammar
|
||
|
*/
|
||
|
|
||
|
block.normal = merge({}, block);
|
||
|
|
||
|
/**
|
||
|
* GFM Block Grammar
|
||
|
*/
|
||
|
|
||
|
block.gfm = merge({}, block.normal, {
|
||
|
fences: /^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,
|
||
|
paragraph: /^/
|
||
|
});
|
||
|
|
||
|
block.gfm.paragraph = replace(block.paragraph)
|
||
|
('(?!', '(?!'
|
||
|
+ block.gfm.fences.source.replace('\\1', '\\2') + '|'
|
||
|
+ block.list.source.replace('\\1', '\\3') + '|')
|
||
|
();
|
||
|
|
||
|
/**
|
||
|
* GFM + Tables Block Grammar
|
||
|
*/
|
||
|
|
||
|
block.tables = merge({}, block.gfm, {
|
||
|
nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
|
||
|
table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
|
||
|
});
|
||
|
|
||
|
/**
|
||
|
* Block Lexer
|
||
|
*/
|
||
|
|
||
|
function Lexer(options) {
|
||
|
this.tokens = [];
|
||
|
this.tokens.links = {};
|
||
|
this.options = options || marked.defaults;
|
||
|
this.rules = block.normal;
|
||
|
|
||
|
if (this.options.gfm) {
|
||
|
if (this.options.tables) {
|
||
|
this.rules = block.tables;
|
||
|
} else {
|
||
|
this.rules = block.gfm;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Expose Block Rules
|
||
|
*/
|
||
|
|
||
|
Lexer.rules = block;
|
||
|
|
||
|
/**
|
||
|
* Static Lex Method
|
||
|
*/
|
||
|
|
||
|
Lexer.lex = function(src, options) {
|
||
|
var lexer = new Lexer(options);
|
||
|
return lexer.lex(src);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Preprocessing
|
||
|
*/
|
||
|
|
||
|
Lexer.prototype.lex = function(src) {
|
||
|
src = src
|
||
|
.replace(/\r\n|\r/g, '\n')
|
||
|
.replace(/\t/g, ' ')
|
||
|
.replace(/\u00a0/g, ' ')
|
||
|
.replace(/\u2424/g, '\n');
|
||
|
|
||
|
return this.token(src, true);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Lexing
|
||
|
*/
|
||
|
|
||
|
Lexer.prototype.token = function(src, top, bq) {
|
||
|
var src = src.replace(/^ +$/gm, '')
|
||
|
, next
|
||
|
, loose
|
||
|
, cap
|
||
|
, bull
|
||
|
, b
|
||
|
, item
|
||
|
, space
|
||
|
, i
|
||
|
, l;
|
||
|
|
||
|
while (src) {
|
||
|
// newline
|
||
|
if (cap = this.rules.newline.exec(src)) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
if (cap[0].length > 1) {
|
||
|
this.tokens.push({
|
||
|
type: 'space'
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// code
|
||
|
if (cap = this.rules.code.exec(src)) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
cap = cap[0].replace(/^ {4}/gm, '');
|
||
|
this.tokens.push({
|
||
|
type: 'code',
|
||
|
text: !this.options.pedantic
|
||
|
? cap.replace(/\n+$/, '')
|
||
|
: cap
|
||
|
});
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// fences (gfm)
|
||
|
if (cap = this.rules.fences.exec(src)) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
this.tokens.push({
|
||
|
type: 'code',
|
||
|
lang: cap[2],
|
||
|
text: cap[3]
|
||
|
});
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// heading
|
||
|
if (cap = this.rules.heading.exec(src)) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
this.tokens.push({
|
||
|
type: 'heading',
|
||
|
depth: cap[1].length,
|
||
|
text: cap[2]
|
||
|
});
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// table no leading pipe (gfm)
|
||
|
if (top && (cap = this.rules.nptable.exec(src))) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
|
||
|
item = {
|
||
|
type: 'table',
|
||
|
header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
|
||
|
align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
|
||
|
cells: cap[3].replace(/\n$/, '').split('\n')
|
||
|
};
|
||
|
|
||
|
for (i = 0; i < item.align.length; i++) {
|
||
|
if (/^ *-+: *$/.test(item.align[i])) {
|
||
|
item.align[i] = 'right';
|
||
|
} else if (/^ *:-+: *$/.test(item.align[i])) {
|
||
|
item.align[i] = 'center';
|
||
|
} else if (/^ *:-+ *$/.test(item.align[i])) {
|
||
|
item.align[i] = 'left';
|
||
|
} else {
|
||
|
item.align[i] = null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < item.cells.length; i++) {
|
||
|
item.cells[i] = item.cells[i].split(/ *\| */);
|
||
|
}
|
||
|
|
||
|
this.tokens.push(item);
|
||
|
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// lheading
|
||
|
if (cap = this.rules.lheading.exec(src)) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
this.tokens.push({
|
||
|
type: 'heading',
|
||
|
depth: cap[2] === '=' ? 1 : 2,
|
||
|
text: cap[1]
|
||
|
});
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// hr
|
||
|
if (cap = this.rules.hr.exec(src)) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
this.tokens.push({
|
||
|
type: 'hr'
|
||
|
});
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// blockquote
|
||
|
if (cap = this.rules.blockquote.exec(src)) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
|
||
|
this.tokens.push({
|
||
|
type: 'blockquote_start'
|
||
|
});
|
||
|
|
||
|
cap = cap[0].replace(/^ *> ?/gm, '');
|
||
|
|
||
|
// Pass `top` to keep the current
|
||
|
// "toplevel" state. This is exactly
|
||
|
// how markdown.pl works.
|
||
|
this.token(cap, top, true);
|
||
|
|
||
|
this.tokens.push({
|
||
|
type: 'blockquote_end'
|
||
|
});
|
||
|
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// list
|
||
|
if (cap = this.rules.list.exec(src)) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
bull = cap[2];
|
||
|
|
||
|
this.tokens.push({
|
||
|
type: 'list_start',
|
||
|
ordered: bull.length > 1
|
||
|
});
|
||
|
|
||
|
// Get each top-level item.
|
||
|
cap = cap[0].match(this.rules.item);
|
||
|
|
||
|
next = false;
|
||
|
l = cap.length;
|
||
|
i = 0;
|
||
|
|
||
|
for (; i < l; i++) {
|
||
|
item = cap[i];
|
||
|
|
||
|
// Remove the list item's bullet
|
||
|
// so it is seen as the next token.
|
||
|
space = item.length;
|
||
|
item = item.replace(/^ *([*+-]|\d+\.) +/, '');
|
||
|
|
||
|
// Outdent whatever the
|
||
|
// list item contains. Hacky.
|
||
|
if (~item.indexOf('\n ')) {
|
||
|
space -= item.length;
|
||
|
item = !this.options.pedantic
|
||
|
? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
|
||
|
: item.replace(/^ {1,4}/gm, '');
|
||
|
}
|
||
|
|
||
|
// Determine whether the next list item belongs here.
|
||
|
// Backpedal if it does not belong in this list.
|
||
|
if (this.options.smartLists && i !== l - 1) {
|
||
|
b = block.bullet.exec(cap[i + 1])[0];
|
||
|
if (bull !== b && !(bull.length > 1 && b.length > 1)) {
|
||
|
src = cap.slice(i + 1).join('\n') + src;
|
||
|
i = l - 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Determine whether item is loose or not.
|
||
|
// Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
|
||
|
// for discount behavior.
|
||
|
loose = next || /\n\n(?!\s*$)/.test(item);
|
||
|
if (i !== l - 1) {
|
||
|
next = item.charAt(item.length - 1) === '\n';
|
||
|
if (!loose) loose = next;
|
||
|
}
|
||
|
|
||
|
this.tokens.push({
|
||
|
type: loose
|
||
|
? 'loose_item_start'
|
||
|
: 'list_item_start'
|
||
|
});
|
||
|
|
||
|
// Recurse.
|
||
|
this.token(item, false, bq);
|
||
|
|
||
|
this.tokens.push({
|
||
|
type: 'list_item_end'
|
||
|
});
|
||
|
}
|
||
|
|
||
|
this.tokens.push({
|
||
|
type: 'list_end'
|
||
|
});
|
||
|
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// html
|
||
|
if (cap = this.rules.html.exec(src)) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
this.tokens.push({
|
||
|
type: this.options.sanitize
|
||
|
? 'paragraph'
|
||
|
: 'html',
|
||
|
pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style',
|
||
|
text: cap[0]
|
||
|
});
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// def
|
||
|
if ((!bq && top) && (cap = this.rules.def.exec(src))) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
this.tokens.links[cap[1].toLowerCase()] = {
|
||
|
href: cap[2],
|
||
|
title: cap[3]
|
||
|
};
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// table (gfm)
|
||
|
if (top && (cap = this.rules.table.exec(src))) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
|
||
|
item = {
|
||
|
type: 'table',
|
||
|
header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
|
||
|
align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
|
||
|
cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
|
||
|
};
|
||
|
|
||
|
for (i = 0; i < item.align.length; i++) {
|
||
|
if (/^ *-+: *$/.test(item.align[i])) {
|
||
|
item.align[i] = 'right';
|
||
|
} else if (/^ *:-+: *$/.test(item.align[i])) {
|
||
|
item.align[i] = 'center';
|
||
|
} else if (/^ *:-+ *$/.test(item.align[i])) {
|
||
|
item.align[i] = 'left';
|
||
|
} else {
|
||
|
item.align[i] = null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < item.cells.length; i++) {
|
||
|
item.cells[i] = item.cells[i]
|
||
|
.replace(/^ *\| *| *\| *$/g, '')
|
||
|
.split(/ *\| */);
|
||
|
}
|
||
|
|
||
|
this.tokens.push(item);
|
||
|
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// top-level paragraph
|
||
|
if (top && (cap = this.rules.paragraph.exec(src))) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
this.tokens.push({
|
||
|
type: 'paragraph',
|
||
|
text: cap[1].charAt(cap[1].length - 1) === '\n'
|
||
|
? cap[1].slice(0, -1)
|
||
|
: cap[1]
|
||
|
});
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// text
|
||
|
if (cap = this.rules.text.exec(src)) {
|
||
|
// Top-level should never reach here.
|
||
|
src = src.substring(cap[0].length);
|
||
|
this.tokens.push({
|
||
|
type: 'text',
|
||
|
text: cap[0]
|
||
|
});
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (src) {
|
||
|
throw new
|
||
|
Error('Infinite loop on byte: ' + src.charCodeAt(0));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return this.tokens;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Inline-Level Grammar
|
||
|
*/
|
||
|
|
||
|
var inline = {
|
||
|
escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
|
||
|
autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
|
||
|
url: noop,
|
||
|
tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
|
||
|
link: /^!?\[(inside)\]\(href\)/,
|
||
|
reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
|
||
|
nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
|
||
|
strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
|
||
|
em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
|
||
|
code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
|
||
|
br: /^ {2,}\n(?!\s*$)/,
|
||
|
del: noop,
|
||
|
text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
|
||
|
};
|
||
|
|
||
|
inline._inside = /(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;
|
||
|
inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
|
||
|
|
||
|
inline.link = replace(inline.link)
|
||
|
('inside', inline._inside)
|
||
|
('href', inline._href)
|
||
|
();
|
||
|
|
||
|
inline.reflink = replace(inline.reflink)
|
||
|
('inside', inline._inside)
|
||
|
();
|
||
|
|
||
|
/**
|
||
|
* Normal Inline Grammar
|
||
|
*/
|
||
|
|
||
|
inline.normal = merge({}, inline);
|
||
|
|
||
|
/**
|
||
|
* Pedantic Inline Grammar
|
||
|
*/
|
||
|
|
||
|
inline.pedantic = merge({}, inline.normal, {
|
||
|
strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
|
||
|
em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
|
||
|
});
|
||
|
|
||
|
/**
|
||
|
* GFM Inline Grammar
|
||
|
*/
|
||
|
|
||
|
inline.gfm = merge({}, inline.normal, {
|
||
|
escape: replace(inline.escape)('])', '~|])')(),
|
||
|
url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
|
||
|
del: /^~~(?=\S)([\s\S]*?\S)~~/,
|
||
|
text: replace(inline.text)
|
||
|
(']|', '~]|')
|
||
|
('|', '|https?://|')
|
||
|
()
|
||
|
});
|
||
|
|
||
|
/**
|
||
|
* GFM + Line Breaks Inline Grammar
|
||
|
*/
|
||
|
|
||
|
inline.breaks = merge({}, inline.gfm, {
|
||
|
br: replace(inline.br)('{2,}', '*')(),
|
||
|
text: replace(inline.gfm.text)('{2,}', '*')()
|
||
|
});
|
||
|
|
||
|
/**
|
||
|
* Inline Lexer & Compiler
|
||
|
*/
|
||
|
|
||
|
function InlineLexer(links, options) {
|
||
|
this.options = options || marked.defaults;
|
||
|
this.links = links;
|
||
|
this.rules = inline.normal;
|
||
|
this.renderer = this.options.renderer || new Renderer;
|
||
|
this.renderer.options = this.options;
|
||
|
|
||
|
if (!this.links) {
|
||
|
throw new
|
||
|
Error('Tokens array requires a `links` property.');
|
||
|
}
|
||
|
|
||
|
if (this.options.gfm) {
|
||
|
if (this.options.breaks) {
|
||
|
this.rules = inline.breaks;
|
||
|
} else {
|
||
|
this.rules = inline.gfm;
|
||
|
}
|
||
|
} else if (this.options.pedantic) {
|
||
|
this.rules = inline.pedantic;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Expose Inline Rules
|
||
|
*/
|
||
|
|
||
|
InlineLexer.rules = inline;
|
||
|
|
||
|
/**
|
||
|
* Static Lexing/Compiling Method
|
||
|
*/
|
||
|
|
||
|
InlineLexer.output = function(src, links, options) {
|
||
|
var inline = new InlineLexer(links, options);
|
||
|
return inline.output(src);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Lexing/Compiling
|
||
|
*/
|
||
|
|
||
|
InlineLexer.prototype.output = function(src) {
|
||
|
var out = ''
|
||
|
, link
|
||
|
, text
|
||
|
, href
|
||
|
, cap;
|
||
|
|
||
|
while (src) {
|
||
|
// escape
|
||
|
if (cap = this.rules.escape.exec(src)) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
out += cap[1];
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// autolink
|
||
|
if (cap = this.rules.autolink.exec(src)) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
if (cap[2] === '@') {
|
||
|
text = cap[1].charAt(6) === ':'
|
||
|
? this.mangle(cap[1].substring(7))
|
||
|
: this.mangle(cap[1]);
|
||
|
href = this.mangle('mailto:') + text;
|
||
|
} else {
|
||
|
text = escape(cap[1]);
|
||
|
href = text;
|
||
|
}
|
||
|
out += this.renderer.link(href, null, text);
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// url (gfm)
|
||
|
if (!this.inLink && (cap = this.rules.url.exec(src))) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
text = escape(cap[1]);
|
||
|
href = text;
|
||
|
out += this.renderer.link(href, null, text);
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// tag
|
||
|
if (cap = this.rules.tag.exec(src)) {
|
||
|
if (!this.inLink && /^<a /i.test(cap[0])) {
|
||
|
this.inLink = true;
|
||
|
} else if (this.inLink && /^<\/a>/i.test(cap[0])) {
|
||
|
this.inLink = false;
|
||
|
}
|
||
|
src = src.substring(cap[0].length);
|
||
|
out += this.options.sanitize
|
||
|
? escape(cap[0])
|
||
|
: cap[0];
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// link
|
||
|
if (cap = this.rules.link.exec(src)) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
this.inLink = true;
|
||
|
out += this.outputLink(cap, {
|
||
|
href: cap[2],
|
||
|
title: cap[3]
|
||
|
});
|
||
|
this.inLink = false;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// reflink, nolink
|
||
|
if ((cap = this.rules.reflink.exec(src))
|
||
|
|| (cap = this.rules.nolink.exec(src))) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
|
||
|
link = this.links[link.toLowerCase()];
|
||
|
if (!link || !link.href) {
|
||
|
out += cap[0].charAt(0);
|
||
|
src = cap[0].substring(1) + src;
|
||
|
continue;
|
||
|
}
|
||
|
this.inLink = true;
|
||
|
out += this.outputLink(cap, link);
|
||
|
this.inLink = false;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// strong
|
||
|
if (cap = this.rules.strong.exec(src)) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
out += this.renderer.strong(this.output(cap[2] || cap[1]));
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// em
|
||
|
if (cap = this.rules.em.exec(src)) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
out += this.renderer.em(this.output(cap[2] || cap[1]));
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// code
|
||
|
if (cap = this.rules.code.exec(src)) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
out += this.renderer.codespan(escape(cap[2], true));
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// br
|
||
|
if (cap = this.rules.br.exec(src)) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
out += this.renderer.br();
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// del (gfm)
|
||
|
if (cap = this.rules.del.exec(src)) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
out += this.renderer.del(this.output(cap[1]));
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// text
|
||
|
if (cap = this.rules.text.exec(src)) {
|
||
|
src = src.substring(cap[0].length);
|
||
|
out += escape(this.smartypants(cap[0]));
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (src) {
|
||
|
throw new
|
||
|
Error('Infinite loop on byte: ' + src.charCodeAt(0));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return out;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Compile Link
|
||
|
*/
|
||
|
|
||
|
InlineLexer.prototype.outputLink = function(cap, link) {
|
||
|
var href = escape(link.href)
|
||
|
, title = link.title ? escape(link.title) : null;
|
||
|
|
||
|
return cap[0].charAt(0) !== '!'
|
||
|
? this.renderer.link(href, title, this.output(cap[1]))
|
||
|
: this.renderer.image(href, title, escape(cap[1]));
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Smartypants Transformations
|
||
|
*/
|
||
|
|
||
|
InlineLexer.prototype.smartypants = function(text) {
|
||
|
if (!this.options.smartypants) return text;
|
||
|
return text
|
||
|
// em-dashes
|
||
|
.replace(/--/g, '\u2014')
|
||
|
// opening singles
|
||
|
.replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
|
||
|
// closing singles & apostrophes
|
||
|
.replace(/'/g, '\u2019')
|
||
|
// opening doubles
|
||
|
.replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
|
||
|
// closing doubles
|
||
|
.replace(/"/g, '\u201d')
|
||
|
// ellipses
|
||
|
.replace(/\.{3}/g, '\u2026');
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Mangle Links
|
||
|
*/
|
||
|
|
||
|
InlineLexer.prototype.mangle = function(text) {
|
||
|
var out = ''
|
||
|
, l = text.length
|
||
|
, i = 0
|
||
|
, ch;
|
||
|
|
||
|
for (; i < l; i++) {
|
||
|
ch = text.charCodeAt(i);
|
||
|
if (Math.random() > 0.5) {
|
||
|
ch = 'x' + ch.toString(16);
|
||
|
}
|
||
|
out += '&#' + ch + ';';
|
||
|
}
|
||
|
|
||
|
return out;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Renderer
|
||
|
*/
|
||
|
|
||
|
function Renderer(options) {
|
||
|
this.options = options || {};
|
||
|
}
|
||
|
|
||
|
Renderer.prototype.code = function(code, lang, escaped) {
|
||
|
if (this.options.highlight) {
|
||
|
var out = this.options.highlight(code, lang);
|
||
|
if (out != null && out !== code) {
|
||
|
escaped = true;
|
||
|
code = out;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!lang) {
|
||
|
return '<pre><code>'
|
||
|
+ (escaped ? code : escape(code, true))
|
||
|
+ '\n</code></pre>';
|
||
|
}
|
||
|
|
||
|
return '<pre><code class="'
|
||
|
+ this.options.langPrefix
|
||
|
+ escape(lang, true)
|
||
|
+ '">'
|
||
|
+ (escaped ? code : escape(code, true))
|
||
|
+ '\n</code></pre>\n';
|
||
|
};
|
||
|
|
||
|
Renderer.prototype.blockquote = function(quote) {
|
||
|
return '<blockquote>\n' + quote + '</blockquote>\n';
|
||
|
};
|
||
|
|
||
|
Renderer.prototype.html = function(html) {
|
||
|
return html;
|
||
|
};
|
||
|
|
||
|
Renderer.prototype.heading = function(text, level, raw) {
|
||
|
return '<h'
|
||
|
+ level
|
||
|
+ ' id="'
|
||
|
+ this.options.headerPrefix
|
||
|
+ raw.toLowerCase().replace(/[^\w]+/g, '-')
|
||
|
+ '">'
|
||
|
+ text
|
||
|
+ '</h'
|
||
|
+ level
|
||
|
+ '>\n';
|
||
|
};
|
||
|
|
||
|
Renderer.prototype.hr = function() {
|
||
|
return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
|
||
|
};
|
||
|
|
||
|
Renderer.prototype.list = function(body, ordered) {
|
||
|
var type = ordered ? 'ol' : 'ul';
|
||
|
return '<' + type + '>\n' + body + '</' + type + '>\n';
|
||
|
};
|
||
|
|
||
|
Renderer.prototype.listitem = function(text) {
|
||
|
return '<li>' + text + '</li>\n';
|
||
|
};
|
||
|
|
||
|
Renderer.prototype.paragraph = function(text) {
|
||
|
return '<p>' + text + '</p>\n';
|
||
|
};
|
||
|
|
||
|
Renderer.prototype.table = function(header, body) {
|
||
|
return '<table>\n'
|
||
|
+ '<thead>\n'
|
||
|
+ header
|
||
|
+ '</thead>\n'
|
||
|
+ '<tbody>\n'
|
||
|
+ body
|
||
|
+ '</tbody>\n'
|
||
|
+ '</table>\n';
|
||
|
};
|
||
|
|
||
|
Renderer.prototype.tablerow = function(content) {
|
||
|
return '<tr>\n' + content + '</tr>\n';
|
||
|
};
|
||
|
|
||
|
Renderer.prototype.tablecell = function(content, flags) {
|
||
|
var type = flags.header ? 'th' : 'td';
|
||
|
var tag = flags.align
|
||
|
? '<' + type + ' style="text-align:' + flags.align + '">'
|
||
|
: '<' + type + '>';
|
||
|
return tag + content + '</' + type + '>\n';
|
||
|
};
|
||
|
|
||
|
// span level renderer
|
||
|
Renderer.prototype.strong = function(text) {
|
||
|
return '<strong>' + text + '</strong>';
|
||
|
};
|
||
|
|
||
|
Renderer.prototype.em = function(text) {
|
||
|
return '<em>' + text + '</em>';
|
||
|
};
|
||
|
|
||
|
Renderer.prototype.codespan = function(text) {
|
||
|
return '<code>' + text + '</code>';
|
||
|
};
|
||
|
|
||
|
Renderer.prototype.br = function() {
|
||
|
return this.options.xhtml ? '<br/>' : '<br>';
|
||
|
};
|
||
|
|
||
|
Renderer.prototype.del = function(text) {
|
||
|
return '<del>' + text + '</del>';
|
||
|
};
|
||
|
|
||
|
Renderer.prototype.link = function(href, title, text) {
|
||
|
if (this.options.sanitize) {
|
||
|
try {
|
||
|
var prot = decodeURIComponent(unescape(href))
|
||
|
.replace(/[^\w:]/g, '')
|
||
|
.toLowerCase();
|
||
|
} catch (e) {
|
||
|
return '';
|
||
|
}
|
||
|
if (prot.indexOf('javascript:') === 0) {
|
||
|
return '';
|
||
|
}
|
||
|
}
|
||
|
var out = '<a href="' + href + '"';
|
||
|
if (title) {
|
||
|
out += ' title="' + title + '"';
|
||
|
}
|
||
|
out += '>' + text + '</a>';
|
||
|
return out;
|
||
|
};
|
||
|
|
||
|
Renderer.prototype.image = function(href, title, text) {
|
||
|
var out = '<img src="' + href + '" alt="' + text + '"';
|
||
|
if (title) {
|
||
|
out += ' title="' + title + '"';
|
||
|
}
|
||
|
out += this.options.xhtml ? '/>' : '>';
|
||
|
return out;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Parsing & Compiling
|
||
|
*/
|
||
|
|
||
|
function Parser(options) {
|
||
|
this.tokens = [];
|
||
|
this.token = null;
|
||
|
this.options = options || marked.defaults;
|
||
|
this.options.renderer = this.options.renderer || new Renderer;
|
||
|
this.renderer = this.options.renderer;
|
||
|
this.renderer.options = this.options;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Static Parse Method
|
||
|
*/
|
||
|
|
||
|
Parser.parse = function(src, options, renderer) {
|
||
|
var parser = new Parser(options, renderer);
|
||
|
return parser.parse(src);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Parse Loop
|
||
|
*/
|
||
|
|
||
|
Parser.prototype.parse = function(src) {
|
||
|
this.inline = new InlineLexer(src.links, this.options, this.renderer);
|
||
|
this.tokens = src.reverse();
|
||
|
|
||
|
var out = '';
|
||
|
while (this.next()) {
|
||
|
out += this.tok();
|
||
|
}
|
||
|
|
||
|
return out;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Next Token
|
||
|
*/
|
||
|
|
||
|
Parser.prototype.next = function() {
|
||
|
return this.token = this.tokens.pop();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Preview Next Token
|
||
|
*/
|
||
|
|
||
|
Parser.prototype.peek = function() {
|
||
|
return this.tokens[this.tokens.length - 1] || 0;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Parse Text Tokens
|
||
|
*/
|
||
|
|
||
|
Parser.prototype.parseText = function() {
|
||
|
var body = this.token.text;
|
||
|
|
||
|
while (this.peek().type === 'text') {
|
||
|
body += '\n' + this.next().text;
|
||
|
}
|
||
|
|
||
|
return this.inline.output(body);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Parse Current Token
|
||
|
*/
|
||
|
|
||
|
Parser.prototype.tok = function() {
|
||
|
switch (this.token.type) {
|
||
|
case 'space': {
|
||
|
return '';
|
||
|
}
|
||
|
case 'hr': {
|
||
|
return this.renderer.hr();
|
||
|
}
|
||
|
case 'heading': {
|
||
|
return this.renderer.heading(
|
||
|
this.inline.output(this.token.text),
|
||
|
this.token.depth,
|
||
|
this.token.text);
|
||
|
}
|
||
|
case 'code': {
|
||
|
return this.renderer.code(this.token.text,
|
||
|
this.token.lang,
|
||
|
this.token.escaped);
|
||
|
}
|
||
|
case 'table': {
|
||
|
var header = ''
|
||
|
, body = ''
|
||
|
, i
|
||
|
, row
|
||
|
, cell
|
||
|
, flags
|
||
|
, j;
|
||
|
|
||
|
// header
|
||
|
cell = '';
|
||
|
for (i = 0; i < this.token.header.length; i++) {
|
||
|
flags = { header: true, align: this.token.align[i] };
|
||
|
cell += this.renderer.tablecell(
|
||
|
this.inline.output(this.token.header[i]),
|
||
|
{ header: true, align: this.token.align[i] }
|
||
|
);
|
||
|
}
|
||
|
header += this.renderer.tablerow(cell);
|
||
|
|
||
|
for (i = 0; i < this.token.cells.length; i++) {
|
||
|
row = this.token.cells[i];
|
||
|
|
||
|
cell = '';
|
||
|
for (j = 0; j < row.length; j++) {
|
||
|
cell += this.renderer.tablecell(
|
||
|
this.inline.output(row[j]),
|
||
|
{ header: false, align: this.token.align[j] }
|
||
|
);
|
||
|
}
|
||
|
|
||
|
body += this.renderer.tablerow(cell);
|
||
|
}
|
||
|
return this.renderer.table(header, body);
|
||
|
}
|
||
|
case 'blockquote_start': {
|
||
|
var body = '';
|
||
|
|
||
|
while (this.next().type !== 'blockquote_end') {
|
||
|
body += this.tok();
|
||
|
}
|
||
|
|
||
|
return this.renderer.blockquote(body);
|
||
|
}
|
||
|
case 'list_start': {
|
||
|
var body = ''
|
||
|
, ordered = this.token.ordered;
|
||
|
|
||
|
while (this.next().type !== 'list_end') {
|
||
|
body += this.tok();
|
||
|
}
|
||
|
|
||
|
return this.renderer.list(body, ordered);
|
||
|
}
|
||
|
case 'list_item_start': {
|
||
|
var body = '';
|
||
|
|
||
|
while (this.next().type !== 'list_item_end') {
|
||
|
body += this.token.type === 'text'
|
||
|
? this.parseText()
|
||
|
: this.tok();
|
||
|
}
|
||
|
|
||
|
return this.renderer.listitem(body);
|
||
|
}
|
||
|
case 'loose_item_start': {
|
||
|
var body = '';
|
||
|
|
||
|
while (this.next().type !== 'list_item_end') {
|
||
|
body += this.tok();
|
||
|
}
|
||
|
|
||
|
return this.renderer.listitem(body);
|
||
|
}
|
||
|
case 'html': {
|
||
|
var html = !this.token.pre && !this.options.pedantic
|
||
|
? this.inline.output(this.token.text)
|
||
|
: this.token.text;
|
||
|
return this.renderer.html(html);
|
||
|
}
|
||
|
case 'paragraph': {
|
||
|
return this.renderer.paragraph(this.inline.output(this.token.text));
|
||
|
}
|
||
|
case 'text': {
|
||
|
return this.renderer.paragraph(this.parseText());
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Helpers
|
||
|
*/
|
||
|
|
||
|
function escape(html, encode) {
|
||
|
return html
|
||
|
.replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&')
|
||
|
.replace(/</g, '<')
|
||
|
.replace(/>/g, '>')
|
||
|
.replace(/"/g, '"')
|
||
|
.replace(/'/g, ''');
|
||
|
}
|
||
|
|
||
|
function unescape(html) {
|
||
|
return html.replace(/&([#\w]+);/g, function(_, n) {
|
||
|
n = n.toLowerCase();
|
||
|
if (n === 'colon') return ':';
|
||
|
if (n.charAt(0) === '#') {
|
||
|
return n.charAt(1) === 'x'
|
||
|
? String.fromCharCode(parseInt(n.substring(2), 16))
|
||
|
: String.fromCharCode(+n.substring(1));
|
||
|
}
|
||
|
return '';
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function replace(regex, opt) {
|
||
|
regex = regex.source;
|
||
|
opt = opt || '';
|
||
|
return function self(name, val) {
|
||
|
if (!name) return new RegExp(regex, opt);
|
||
|
val = val.source || val;
|
||
|
val = val.replace(/(^|[^\[])\^/g, '$1');
|
||
|
regex = regex.replace(name, val);
|
||
|
return self;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function noop() {}
|
||
|
noop.exec = noop;
|
||
|
|
||
|
function merge(obj) {
|
||
|
var i = 1
|
||
|
, target
|
||
|
, key;
|
||
|
|
||
|
for (; i < arguments.length; i++) {
|
||
|
target = arguments[i];
|
||
|
for (key in target) {
|
||
|
if (Object.prototype.hasOwnProperty.call(target, key)) {
|
||
|
obj[key] = target[key];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return obj;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Marked
|
||
|
*/
|
||
|
|
||
|
function marked(src, opt, callback) {
|
||
|
if (callback || typeof opt === 'function') {
|
||
|
if (!callback) {
|
||
|
callback = opt;
|
||
|
opt = null;
|
||
|
}
|
||
|
|
||
|
opt = merge({}, marked.defaults, opt || {});
|
||
|
|
||
|
var highlight = opt.highlight
|
||
|
, tokens
|
||
|
, pending
|
||
|
, i = 0;
|
||
|
|
||
|
try {
|
||
|
tokens = Lexer.lex(src, opt)
|
||
|
} catch (e) {
|
||
|
return callback(e);
|
||
|
}
|
||
|
|
||
|
pending = tokens.length;
|
||
|
|
||
|
var done = function() {
|
||
|
var out, err;
|
||
|
|
||
|
try {
|
||
|
out = Parser.parse(tokens, opt);
|
||
|
} catch (e) {
|
||
|
err = e;
|
||
|
}
|
||
|
|
||
|
opt.highlight = highlight;
|
||
|
|
||
|
return err
|
||
|
? callback(err)
|
||
|
: callback(null, out);
|
||
|
};
|
||
|
|
||
|
if (!highlight || highlight.length < 3) {
|
||
|
return done();
|
||
|
}
|
||
|
|
||
|
delete opt.highlight;
|
||
|
|
||
|
if (!pending) return done();
|
||
|
|
||
|
for (; i < tokens.length; i++) {
|
||
|
(function(token) {
|
||
|
if (token.type !== 'code') {
|
||
|
return --pending || done();
|
||
|
}
|
||
|
return highlight(token.text, token.lang, function(err, code) {
|
||
|
if (code == null || code === token.text) {
|
||
|
return --pending || done();
|
||
|
}
|
||
|
token.text = code;
|
||
|
token.escaped = true;
|
||
|
--pending || done();
|
||
|
});
|
||
|
})(tokens[i]);
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
try {
|
||
|
if (opt) opt = merge({}, marked.defaults, opt);
|
||
|
return Parser.parse(Lexer.lex(src, opt), opt);
|
||
|
} catch (e) {
|
||
|
e.message += '\nPlease report this to https://github.com/chjj/marked.';
|
||
|
if ((opt || marked.defaults).silent) {
|
||
|
return '<p>An error occured:</p><pre>'
|
||
|
+ escape(e.message + '', true)
|
||
|
+ '</pre>';
|
||
|
}
|
||
|
throw e;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Options
|
||
|
*/
|
||
|
|
||
|
marked.options =
|
||
|
marked.setOptions = function(opt) {
|
||
|
merge(marked.defaults, opt);
|
||
|
return marked;
|
||
|
};
|
||
|
|
||
|
marked.defaults = {
|
||
|
gfm: true,
|
||
|
tables: true,
|
||
|
breaks: false,
|
||
|
pedantic: false,
|
||
|
sanitize: false,
|
||
|
smartLists: false,
|
||
|
silent: false,
|
||
|
highlight: null,
|
||
|
langPrefix: 'lang-',
|
||
|
smartypants: false,
|
||
|
headerPrefix: '',
|
||
|
renderer: new Renderer,
|
||
|
xhtml: false
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Expose
|
||
|
*/
|
||
|
|
||
|
marked.Parser = Parser;
|
||
|
marked.parser = Parser.parse;
|
||
|
|
||
|
marked.Renderer = Renderer;
|
||
|
|
||
|
marked.Lexer = Lexer;
|
||
|
marked.lexer = Lexer.lex;
|
||
|
|
||
|
marked.InlineLexer = InlineLexer;
|
||
|
marked.inlineLexer = InlineLexer.output;
|
||
|
|
||
|
marked.parse = marked;
|
||
|
|
||
|
if (typeof exports === 'object') {
|
||
|
module.exports = marked;
|
||
|
} else if (typeof define === 'function' && define.amd) {
|
||
|
define(function() { return marked; });
|
||
|
} else {
|
||
|
this.marked = marked;
|
||
|
}
|
||
|
|
||
|
}).call(function() {
|
||
|
return this || (typeof window !== 'undefined' ? window : global);
|
||
|
}());
|
||
|
</script>
|
||
|
|
||
|
|
||
|
<!--
|
||
|
Element wrapper for the `marked` (http://marked.org/) library.
|
||
|
|
||
|
@class marked-element
|
||
|
@blurb Element wrapper for the marked library.
|
||
|
@status alpha
|
||
|
@snap snap.png
|
||
|
-->
|
||
|
<polymer-element name="marked-element" attributes="text" assetpath="../marked-element/">
|
||
|
<script>
|
||
|
|
||
|
Polymer('marked-element', {
|
||
|
|
||
|
text: '',
|
||
|
|
||
|
attached: function() {
|
||
|
marked.setOptions({
|
||
|
highlight: this.highlight.bind(this)
|
||
|
});
|
||
|
if (!this.text) {
|
||
|
this.text = this.innerHTML;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
textChanged: function () {
|
||
|
this.innerHTML = marked(this.text);
|
||
|
},
|
||
|
|
||
|
highlight: function(code, lang) {
|
||
|
var event = this.fire('marked-js-highlight', {code: code, lang: lang});
|
||
|
return event.detail.code || code;
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
</script>
|
||
|
</polymer-element>
|
||
|
|
||
|
|
||
|
<script>// Copyright (C) 2006 Google Inc.
|
||
|
//
|
||
|
// 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.
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @fileoverview
|
||
|
* some functions for browser-side pretty printing of code contained in html.
|
||
|
*
|
||
|
* <p>
|
||
|
* For a fairly comprehensive set of languages see the
|
||
|
* <a href="http://google-code-prettify.googlecode.com/svn/trunk/README.html#langs">README</a>
|
||
|
* file that came with this source. At a minimum, the lexer should work on a
|
||
|
* number of languages including C and friends, Java, Python, Bash, SQL, HTML,
|
||
|
* XML, CSS, Javascript, and Makefiles. It works passably on Ruby, PHP and Awk
|
||
|
* and a subset of Perl, but, because of commenting conventions, doesn't work on
|
||
|
* Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class.
|
||
|
* <p>
|
||
|
* Usage: <ol>
|
||
|
* <li> include this source file in an html page via
|
||
|
* {@code <script type="text/javascript" src="/path/to/prettify.js"><\/script>}
|
||
|
* <li> define style rules. See the example page for examples.
|
||
|
* <li> mark the {@code <pre>} and {@code <code>} tags in your source with
|
||
|
* {@code class=prettyprint.}
|
||
|
* You can also use the (html deprecated) {@code <xmp>} tag, but the pretty
|
||
|
* printer needs to do more substantial DOM manipulations to support that, so
|
||
|
* some css styles may not be preserved.
|
||
|
* </ol>
|
||
|
* That's it. I wanted to keep the API as simple as possible, so there's no
|
||
|
* need to specify which language the code is in, but if you wish, you can add
|
||
|
* another class to the {@code <pre>} or {@code <code>} element to specify the
|
||
|
* language, as in {@code <pre class="prettyprint lang-java">}. Any class that
|
||
|
* starts with "lang-" followed by a file extension, specifies the file type.
|
||
|
* See the "lang-*.js" files in this directory for code that implements
|
||
|
* per-language file handlers.
|
||
|
* <p>
|
||
|
* Change log:<br>
|
||
|
* cbeust, 2006/08/22
|
||
|
* <blockquote>
|
||
|
* Java annotations (start with "@") are now captured as literals ("lit")
|
||
|
* </blockquote>
|
||
|
* @requires console
|
||
|
*/
|
||
|
|
||
|
// JSLint declarations
|
||
|
/*global console, document, navigator, setTimeout, window, define */
|
||
|
|
||
|
/**
|
||
|
* Split {@code prettyPrint} into multiple timeouts so as not to interfere with
|
||
|
* UI events.
|
||
|
* If set to {@code false}, {@code prettyPrint()} is synchronous.
|
||
|
*/
|
||
|
window['PR_SHOULD_USE_CONTINUATION'] = true;
|
||
|
|
||
|
/**
|
||
|
* Find all the {@code <pre>} and {@code <code>} tags in the DOM with
|
||
|
* {@code class=prettyprint} and prettify them.
|
||
|
*
|
||
|
* @param {Function?} opt_whenDone if specified, called when the last entry
|
||
|
* has been finished.
|
||
|
*/
|
||
|
var prettyPrintOne;
|
||
|
/**
|
||
|
* Pretty print a chunk of code.
|
||
|
*
|
||
|
* @param {string} sourceCodeHtml code as html
|
||
|
* @return {string} code as html, but prettier
|
||
|
*/
|
||
|
var prettyPrint;
|
||
|
|
||
|
|
||
|
(function () {
|
||
|
var win = window;
|
||
|
// Keyword lists for various languages.
|
||
|
// We use things that coerce to strings to make them compact when minified
|
||
|
// and to defeat aggressive optimizers that fold large string constants.
|
||
|
var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"];
|
||
|
var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," +
|
||
|
"double,enum,extern,float,goto,int,long,register,short,signed,sizeof," +
|
||
|
"static,struct,switch,typedef,union,unsigned,void,volatile"];
|
||
|
var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," +
|
||
|
"new,operator,private,protected,public,this,throw,true,try,typeof"];
|
||
|
var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignof,align_union,asm,axiom,bool," +
|
||
|
"concept,concept_map,const_cast,constexpr,decltype," +
|
||
|
"dynamic_cast,explicit,export,friend,inline,late_check," +
|
||
|
"mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast," +
|
||
|
"template,typeid,typename,using,virtual,where"];
|
||
|
var JAVA_KEYWORDS = [COMMON_KEYWORDS,
|
||
|
"abstract,boolean,byte,extends,final,finally,implements,import," +
|
||
|
"instanceof,null,native,package,strictfp,super,synchronized,throws," +
|
||
|
"transient"];
|
||
|
var CSHARP_KEYWORDS = [JAVA_KEYWORDS,
|
||
|
"as,base,by,checked,decimal,delegate,descending,dynamic,event," +
|
||
|
"fixed,foreach,from,group,implicit,in,interface,internal,into,is,let," +
|
||
|
"lock,object,out,override,orderby,params,partial,readonly,ref,sbyte," +
|
||
|
"sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort," +
|
||
|
"var,virtual,where"];
|
||
|
var COFFEE_KEYWORDS = "all,and,by,catch,class,else,extends,false,finally," +
|
||
|
"for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then," +
|
||
|
"throw,true,try,unless,until,when,while,yes";
|
||
|
var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS,
|
||
|
"debugger,eval,export,function,get,null,set,undefined,var,with," +
|
||
|
"Infinity,NaN"];
|
||
|
var PERL_KEYWORDS = "caller,delete,die,do,dump,elsif,eval,exit,foreach,for," +
|
||
|
"goto,if,import,last,local,my,next,no,our,print,package,redo,require," +
|
||
|
"sub,undef,unless,until,use,wantarray,while,BEGIN,END";
|
||
|
var PYTHON_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "and,as,assert,class,def,del," +
|
||
|
"elif,except,exec,finally,from,global,import,in,is,lambda," +
|
||
|
"nonlocal,not,or,pass,print,raise,try,with,yield," +
|
||
|
"False,True,None"];
|
||
|
var RUBY_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "alias,and,begin,case,class," +
|
||
|
"def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo," +
|
||
|
"rescue,retry,self,super,then,true,undef,unless,until,when,yield," +
|
||
|
"BEGIN,END"];
|
||
|
var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "case,done,elif,esac,eval,fi," +
|
||
|
"function,in,local,set,then,until"];
|
||
|
var ALL_KEYWORDS = [
|
||
|
CPP_KEYWORDS, CSHARP_KEYWORDS, JSCRIPT_KEYWORDS, PERL_KEYWORDS +
|
||
|
PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS];
|
||
|
var C_TYPES = /^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)\b/;
|
||
|
|
||
|
// token style names. correspond to css classes
|
||
|
/**
|
||
|
* token style for a string literal
|
||
|
* @const
|
||
|
*/
|
||
|
var PR_STRING = 'str';
|
||
|
/**
|
||
|
* token style for a keyword
|
||
|
* @const
|
||
|
*/
|
||
|
var PR_KEYWORD = 'kwd';
|
||
|
/**
|
||
|
* token style for a comment
|
||
|
* @const
|
||
|
*/
|
||
|
var PR_COMMENT = 'com';
|
||
|
/**
|
||
|
* token style for a type
|
||
|
* @const
|
||
|
*/
|
||
|
var PR_TYPE = 'typ';
|
||
|
/**
|
||
|
* token style for a literal value. e.g. 1, null, true.
|
||
|
* @const
|
||
|
*/
|
||
|
var PR_LITERAL = 'lit';
|
||
|
/**
|
||
|
* token style for a punctuation string.
|
||
|
* @const
|
||
|
*/
|
||
|
var PR_PUNCTUATION = 'pun';
|
||
|
/**
|
||
|
* token style for plain text.
|
||
|
* @const
|
||
|
*/
|
||
|
var PR_PLAIN = 'pln';
|
||
|
|
||
|
/**
|
||
|
* token style for an sgml tag.
|
||
|
* @const
|
||
|
*/
|
||
|
var PR_TAG = 'tag';
|
||
|
/**
|
||
|
* token style for a markup declaration such as a DOCTYPE.
|
||
|
* @const
|
||
|
*/
|
||
|
var PR_DECLARATION = 'dec';
|
||
|
/**
|
||
|
* token style for embedded source.
|
||
|
* @const
|
||
|
*/
|
||
|
var PR_SOURCE = 'src';
|
||
|
/**
|
||
|
* token style for an sgml attribute name.
|
||
|
* @const
|
||
|
*/
|
||
|
var PR_ATTRIB_NAME = 'atn';
|
||
|
/**
|
||
|
* token style for an sgml attribute value.
|
||
|
* @const
|
||
|
*/
|
||
|
var PR_ATTRIB_VALUE = 'atv';
|
||
|
|
||
|
/**
|
||
|
* A class that indicates a section of markup that is not code, e.g. to allow
|
||
|
* embedding of line numbers within code listings.
|
||
|
* @const
|
||
|
*/
|
||
|
var PR_NOCODE = 'nocode';
|
||
|
|
||
|
|
||
|
|
||
|
/**
|
||
|
* A set of tokens that can precede a regular expression literal in
|
||
|
* javascript
|
||
|
* http://web.archive.org/web/20070717142515/http://www.mozilla.org/js/language/js20/rationale/syntax.html
|
||
|
* has the full list, but I've removed ones that might be problematic when
|
||
|
* seen in languages that don't support regular expression literals.
|
||
|
*
|
||
|
* <p>Specifically, I've removed any keywords that can't precede a regexp
|
||
|
* literal in a syntactically legal javascript program, and I've removed the
|
||
|
* "in" keyword since it's not a keyword in many languages, and might be used
|
||
|
* as a count of inches.
|
||
|
*
|
||
|
* <p>The link above does not accurately describe EcmaScript rules since
|
||
|
* it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
|
||
|
* very well in practice.
|
||
|
*
|
||
|
* @private
|
||
|
* @const
|
||
|
*/
|
||
|
var REGEXP_PRECEDER_PATTERN = '(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*';
|
||
|
|
||
|
// CAVEAT: this does not properly handle the case where a regular
|
||
|
// expression immediately follows another since a regular expression may
|
||
|
// have flags for case-sensitivity and the like. Having regexp tokens
|
||
|
// adjacent is not valid in any language I'm aware of, so I'm punting.
|
||
|
// TODO: maybe style special characters inside a regexp as punctuation.
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
|
||
|
* matches the union of the sets of strings matched by the input RegExp.
|
||
|
* Since it matches globally, if the input strings have a start-of-input
|
||
|
* anchor (/^.../), it is ignored for the purposes of unioning.
|
||
|
* @param {Array.<RegExp>} regexs non multiline, non-global regexs.
|
||
|
* @return {RegExp} a global regex.
|
||
|
*/
|
||
|
function combinePrefixPatterns(regexs) {
|
||
|
var capturedGroupIndex = 0;
|
||
|
|
||
|
var needToFoldCase = false;
|
||
|
var ignoreCase = false;
|
||
|
for (var i = 0, n = regexs.length; i < n; ++i) {
|
||
|
var regex = regexs[i];
|
||
|
if (regex.ignoreCase) {
|
||
|
ignoreCase = true;
|
||
|
} else if (/[a-z]/i.test(regex.source.replace(
|
||
|
/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
|
||
|
needToFoldCase = true;
|
||
|
ignoreCase = false;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var escapeCharToCodeUnit = {
|
||
|
'b': 8,
|
||
|
't': 9,
|
||
|
'n': 0xa,
|
||
|
'v': 0xb,
|
||
|
'f': 0xc,
|
||
|
'r': 0xd
|
||
|
};
|
||
|
|
||
|
function decodeEscape(charsetPart) {
|
||
|
var cc0 = charsetPart.charCodeAt(0);
|
||
|
if (cc0 !== 92 /* \\ */) {
|
||
|
return cc0;
|
||
|
}
|
||
|
var c1 = charsetPart.charAt(1);
|
||
|
cc0 = escapeCharToCodeUnit[c1];
|
||
|
if (cc0) {
|
||
|
return cc0;
|
||
|
} else if ('0' <= c1 && c1 <= '7') {
|
||
|
return parseInt(charsetPart.substring(1), 8);
|
||
|
} else if (c1 === 'u' || c1 === 'x') {
|
||
|
return parseInt(charsetPart.substring(2), 16);
|
||
|
} else {
|
||
|
return charsetPart.charCodeAt(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function encodeEscape(charCode) {
|
||
|
if (charCode < 0x20) {
|
||
|
return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
|
||
|
}
|
||
|
var ch = String.fromCharCode(charCode);
|
||
|
return (ch === '\\' || ch === '-' || ch === ']' || ch === '^')
|
||
|
? "\\" + ch : ch;
|
||
|
}
|
||
|
|
||
|
function caseFoldCharset(charSet) {
|
||
|
var charsetParts = charSet.substring(1, charSet.length - 1).match(
|
||
|
new RegExp(
|
||
|
'\\\\u[0-9A-Fa-f]{4}'
|
||
|
+ '|\\\\x[0-9A-Fa-f]{2}'
|
||
|
+ '|\\\\[0-3][0-7]{0,2}'
|
||
|
+ '|\\\\[0-7]{1,2}'
|
||
|
+ '|\\\\[\\s\\S]'
|
||
|
+ '|-'
|
||
|
+ '|[^-\\\\]',
|
||
|
'g'));
|
||
|
var ranges = [];
|
||
|
var inverse = charsetParts[0] === '^';
|
||
|
|
||
|
var out = ['['];
|
||
|
if (inverse) { out.push('^'); }
|
||
|
|
||
|
for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
|
||
|
var p = charsetParts[i];
|
||
|
if (/\\[bdsw]/i.test(p)) { // Don't muck with named groups.
|
||
|
out.push(p);
|
||
|
} else {
|
||
|
var start = decodeEscape(p);
|
||
|
var end;
|
||
|
if (i + 2 < n && '-' === charsetParts[i + 1]) {
|
||
|
end = decodeEscape(charsetParts[i + 2]);
|
||
|
i += 2;
|
||
|
} else {
|
||
|
end = start;
|
||
|
}
|
||
|
ranges.push([start, end]);
|
||
|
// If the range might intersect letters, then expand it.
|
||
|
// This case handling is too simplistic.
|
||
|
// It does not deal with non-latin case folding.
|
||
|
// It works for latin source code identifiers though.
|
||
|
if (!(end < 65 || start > 122)) {
|
||
|
if (!(end < 65 || start > 90)) {
|
||
|
ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
|
||
|
}
|
||
|
if (!(end < 97 || start > 122)) {
|
||
|
ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
|
||
|
// -> [[1, 12], [14, 14], [16, 17]]
|
||
|
ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1] - a[1]); });
|
||
|
var consolidatedRanges = [];
|
||
|
var lastRange = [];
|
||
|
for (var i = 0; i < ranges.length; ++i) {
|
||
|
var range = ranges[i];
|
||
|
if (range[0] <= lastRange[1] + 1) {
|
||
|
lastRange[1] = Math.max(lastRange[1], range[1]);
|
||
|
} else {
|
||
|
consolidatedRanges.push(lastRange = range);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (var i = 0; i < consolidatedRanges.length; ++i) {
|
||
|
var range = consolidatedRanges[i];
|
||
|
out.push(encodeEscape(range[0]));
|
||
|
if (range[1] > range[0]) {
|
||
|
if (range[1] + 1 > range[0]) { out.push('-'); }
|
||
|
out.push(encodeEscape(range[1]));
|
||
|
}
|
||
|
}
|
||
|
out.push(']');
|
||
|
return out.join('');
|
||
|
}
|
||
|
|
||
|
function allowAnywhereFoldCaseAndRenumberGroups(regex) {
|
||
|
// Split into character sets, escape sequences, punctuation strings
|
||
|
// like ('(', '(?:', ')', '^'), and runs of characters that do not
|
||
|
// include any of the above.
|
||
|
var parts = regex.source.match(
|
||
|
new RegExp(
|
||
|
'(?:'
|
||
|
+ '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]' // a character set
|
||
|
+ '|\\\\u[A-Fa-f0-9]{4}' // a unicode escape
|
||
|
+ '|\\\\x[A-Fa-f0-9]{2}' // a hex escape
|
||
|
+ '|\\\\[0-9]+' // a back-reference or octal escape
|
||
|
+ '|\\\\[^ux0-9]' // other escape sequence
|
||
|
+ '|\\(\\?[:!=]' // start of a non-capturing group
|
||
|
+ '|[\\(\\)\\^]' // start/end of a group, or line start
|
||
|
+ '|[^\\x5B\\x5C\\(\\)\\^]+' // run of other characters
|
||
|
+ ')',
|
||
|
'g'));
|
||
|
var n = parts.length;
|
||
|
|
||
|
// Maps captured group numbers to the number they will occupy in
|
||
|
// the output or to -1 if that has not been determined, or to
|
||
|
// undefined if they need not be capturing in the output.
|
||
|
var capturedGroups = [];
|
||
|
|
||
|
// Walk over and identify back references to build the capturedGroups
|
||
|
// mapping.
|
||
|
for (var i = 0, groupIndex = 0; i < n; ++i) {
|
||
|
var p = parts[i];
|
||
|
if (p === '(') {
|
||
|
// groups are 1-indexed, so max group index is count of '('
|
||
|
++groupIndex;
|
||
|
} else if ('\\' === p.charAt(0)) {
|
||
|
var decimalValue = +p.substring(1);
|
||
|
if (decimalValue) {
|
||
|
if (decimalValue <= groupIndex) {
|
||
|
capturedGroups[decimalValue] = -1;
|
||
|
} else {
|
||
|
// Replace with an unambiguous escape sequence so that
|
||
|
// an octal escape sequence does not turn into a backreference
|
||
|
// to a capturing group from an earlier regex.
|
||
|
parts[i] = encodeEscape(decimalValue);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Renumber groups and reduce capturing groups to non-capturing groups
|
||
|
// where possible.
|
||
|
for (var i = 1; i < capturedGroups.length; ++i) {
|
||
|
if (-1 === capturedGroups[i]) {
|
||
|
capturedGroups[i] = ++capturedGroupIndex;
|
||
|
}
|
||
|
}
|
||
|
for (var i = 0, groupIndex = 0; i < n; ++i) {
|
||
|
var p = parts[i];
|
||
|
if (p === '(') {
|
||
|
++groupIndex;
|
||
|
if (!capturedGroups[groupIndex]) {
|
||
|
parts[i] = '(?:';
|
||
|
}
|
||
|
} else if ('\\' === p.charAt(0)) {
|
||
|
var decimalValue = +p.substring(1);
|
||
|
if (decimalValue && decimalValue <= groupIndex) {
|
||
|
parts[i] = '\\' + capturedGroups[decimalValue];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Remove any prefix anchors so that the output will match anywhere.
|
||
|
// ^^ really does mean an anchored match though.
|
||
|
for (var i = 0; i < n; ++i) {
|
||
|
if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
|
||
|
}
|
||
|
|
||
|
// Expand letters to groups to handle mixing of case-sensitive and
|
||
|
// case-insensitive patterns if necessary.
|
||
|
if (regex.ignoreCase && needToFoldCase) {
|
||
|
for (var i = 0; i < n; ++i) {
|
||
|
var p = parts[i];
|
||
|
var ch0 = p.charAt(0);
|
||
|
if (p.length >= 2 && ch0 === '[') {
|
||
|
parts[i] = caseFoldCharset(p);
|
||
|
} else if (ch0 !== '\\') {
|
||
|
// TODO: handle letters in numeric escapes.
|
||
|
parts[i] = p.replace(
|
||
|
/[a-zA-Z]/g,
|
||
|
function (ch) {
|
||
|
var cc = ch.charCodeAt(0);
|
||
|
return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return parts.join('');
|
||
|
}
|
||
|
|
||
|
var rewritten = [];
|
||
|
for (var i = 0, n = regexs.length; i < n; ++i) {
|
||
|
var regex = regexs[i];
|
||
|
if (regex.global || regex.multiline) { throw new Error('' + regex); }
|
||
|
rewritten.push(
|
||
|
'(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
|
||
|
}
|
||
|
|
||
|
return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Split markup into a string of source code and an array mapping ranges in
|
||
|
* that string to the text nodes in which they appear.
|
||
|
*
|
||
|
* <p>
|
||
|
* The HTML DOM structure:</p>
|
||
|
* <pre>
|
||
|
* (Element "p"
|
||
|
* (Element "b"
|
||
|
* (Text "print ")) ; #1
|
||
|
* (Text "'Hello '") ; #2
|
||
|
* (Element "br") ; #3
|
||
|
* (Text " + 'World';")) ; #4
|
||
|
* </pre>
|
||
|
* <p>
|
||
|
* corresponds to the HTML
|
||
|
* {@code <p><b>print </b>'Hello '<br> + 'World';</p>}.</p>
|
||
|
*
|
||
|
* <p>
|
||
|
* It will produce the output:</p>
|
||
|
* <pre>
|
||
|
* {
|
||
|
* sourceCode: "print 'Hello '\n + 'World';",
|
||
|
* // 1 2
|
||
|
* // 012345678901234 5678901234567
|
||
|
* spans: [0, #1, 6, #2, 14, #3, 15, #4]
|
||
|
* }
|
||
|
* </pre>
|
||
|
* <p>
|
||
|
* where #1 is a reference to the {@code "print "} text node above, and so
|
||
|
* on for the other text nodes.
|
||
|
* </p>
|
||
|
*
|
||
|
* <p>
|
||
|
* The {@code} spans array is an array of pairs. Even elements are the start
|
||
|
* indices of substrings, and odd elements are the text nodes (or BR elements)
|
||
|
* that contain the text for those substrings.
|
||
|
* Substrings continue until the next index or the end of the source.
|
||
|
* </p>
|
||
|
*
|
||
|
* @param {Node} node an HTML DOM subtree containing source-code.
|
||
|
* @param {boolean} isPreformatted true if white-space in text nodes should
|
||
|
* be considered significant.
|
||
|
* @return {Object} source code and the text nodes in which they occur.
|
||
|
*/
|
||
|
function extractSourceSpans(node, isPreformatted) {
|
||
|
var nocode = /(?:^|\s)nocode(?:\s|$)/;
|
||
|
|
||
|
var chunks = [];
|
||
|
var length = 0;
|
||
|
var spans = [];
|
||
|
var k = 0;
|
||
|
|
||
|
function walk(node) {
|
||
|
switch (node.nodeType) {
|
||
|
case 1: // Element
|
||
|
if (nocode.test(node.className)) { return; }
|
||
|
for (var child = node.firstChild; child; child = child.nextSibling) {
|
||
|
walk(child);
|
||
|
}
|
||
|
var nodeName = node.nodeName.toLowerCase();
|
||
|
if ('br' === nodeName || 'li' === nodeName) {
|
||
|
chunks[k] = '\n';
|
||
|
spans[k << 1] = length++;
|
||
|
spans[(k++ << 1) | 1] = node;
|
||
|
}
|
||
|
break;
|
||
|
case 3: case 4: // Text
|
||
|
var text = node.nodeValue;
|
||
|
if (text.length) {
|
||
|
if (!isPreformatted) {
|
||
|
text = text.replace(/[ \t\r\n]+/g, ' ');
|
||
|
} else {
|
||
|
text = text.replace(/\r\n?/g, '\n'); // Normalize newlines.
|
||
|
}
|
||
|
// TODO: handle tabs here?
|
||
|
chunks[k] = text;
|
||
|
spans[k << 1] = length;
|
||
|
length += text.length;
|
||
|
spans[(k++ << 1) | 1] = node;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
walk(node);
|
||
|
|
||
|
return {
|
||
|
sourceCode: chunks.join('').replace(/\n$/, ''),
|
||
|
spans: spans
|
||
|
};
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Apply the given language handler to sourceCode and add the resulting
|
||
|
* decorations to out.
|
||
|
* @param {number} basePos the index of sourceCode within the chunk of source
|
||
|
* whose decorations are already present on out.
|
||
|
*/
|
||
|
function appendDecorations(basePos, sourceCode, langHandler, out) {
|
||
|
if (!sourceCode) { return; }
|
||
|
var job = {
|
||
|
sourceCode: sourceCode,
|
||
|
basePos: basePos
|
||
|
};
|
||
|
langHandler(job);
|
||
|
out.push.apply(out, job.decorations);
|
||
|
}
|
||
|
|
||
|
var notWs = /\S/;
|
||
|
|
||
|
/**
|
||
|
* Given an element, if it contains only one child element and any text nodes
|
||
|
* it contains contain only space characters, return the sole child element.
|
||
|
* Otherwise returns undefined.
|
||
|
* <p>
|
||
|
* This is meant to return the CODE element in {@code <pre><code ...>} when
|
||
|
* there is a single child element that contains all the non-space textual
|
||
|
* content, but not to return anything where there are multiple child elements
|
||
|
* as in {@code <pre><code>...</code><code>...</code></pre>} or when there
|
||
|
* is textual content.
|
||
|
*/
|
||
|
function childContentWrapper(element) {
|
||
|
var wrapper = undefined;
|
||
|
for (var c = element.firstChild; c; c = c.nextSibling) {
|
||
|
var type = c.nodeType;
|
||
|
wrapper = (type === 1) // Element Node
|
||
|
? (wrapper ? element : c)
|
||
|
: (type === 3) // Text Node
|
||
|
? (notWs.test(c.nodeValue) ? element : wrapper)
|
||
|
: wrapper;
|
||
|
}
|
||
|
return wrapper === element ? undefined : wrapper;
|
||
|
}
|
||
|
|
||
|
/** Given triples of [style, pattern, context] returns a lexing function,
|
||
|
* The lexing function interprets the patterns to find token boundaries and
|
||
|
* returns a decoration list of the form
|
||
|
* [index_0, style_0, index_1, style_1, ..., index_n, style_n]
|
||
|
* where index_n is an index into the sourceCode, and style_n is a style
|
||
|
* constant like PR_PLAIN. index_n-1 <= index_n, and style_n-1 applies to
|
||
|
* all characters in sourceCode[index_n-1:index_n].
|
||
|
*
|
||
|
* The stylePatterns is a list whose elements have the form
|
||
|
* [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
|
||
|
*
|
||
|
* Style is a style constant like PR_PLAIN, or can be a string of the
|
||
|
* form 'lang-FOO', where FOO is a language extension describing the
|
||
|
* language of the portion of the token in $1 after pattern executes.
|
||
|
* E.g., if style is 'lang-lisp', and group 1 contains the text
|
||
|
* '(hello (world))', then that portion of the token will be passed to the
|
||
|
* registered lisp handler for formatting.
|
||
|
* The text before and after group 1 will be restyled using this decorator
|
||
|
* so decorators should take care that this doesn't result in infinite
|
||
|
* recursion. For example, the HTML lexer rule for SCRIPT elements looks
|
||
|
* something like ['lang-js', /<[s]cript>(.+?)<\/script>/]. This may match
|
||
|
* '<script>foo()<\/script>', which would cause the current decorator to
|
||
|
* be called with '<script>' which would not match the same rule since
|
||
|
* group 1 must not be empty, so it would be instead styled as PR_TAG by
|
||
|
* the generic tag rule. The handler registered for the 'js' extension would
|
||
|
* then be called with 'foo()', and finally, the current decorator would
|
||
|
* be called with '<\/script>' which would not match the original rule and
|
||
|
* so the generic tag rule would identify it as a tag.
|
||
|
*
|
||
|
* Pattern must only match prefixes, and if it matches a prefix, then that
|
||
|
* match is considered a token with the same style.
|
||
|
*
|
||
|
* Context is applied to the last non-whitespace, non-comment token
|
||
|
* recognized.
|
||
|
*
|
||
|
* Shortcut is an optional string of characters, any of which, if the first
|
||
|
* character, gurantee that this pattern and only this pattern matches.
|
||
|
*
|
||
|
* @param {Array} shortcutStylePatterns patterns that always start with
|
||
|
* a known character. Must have a shortcut string.
|
||
|
* @param {Array} fallthroughStylePatterns patterns that will be tried in
|
||
|
* order if the shortcut ones fail. May have shortcuts.
|
||
|
*
|
||
|
* @return {function (Object)} a
|
||
|
* function that takes source code and returns a list of decorations.
|
||
|
*/
|
||
|
function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
|
||
|
var shortcuts = {};
|
||
|
var tokenizer;
|
||
|
(function () {
|
||
|
var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
|
||
|
var allRegexs = [];
|
||
|
var regexKeys = {};
|
||
|
for (var i = 0, n = allPatterns.length; i < n; ++i) {
|
||
|
var patternParts = allPatterns[i];
|
||
|
var shortcutChars = patternParts[3];
|
||
|
if (shortcutChars) {
|
||
|
for (var c = shortcutChars.length; --c >= 0;) {
|
||
|
shortcuts[shortcutChars.charAt(c)] = patternParts;
|
||
|
}
|
||
|
}
|
||
|
var regex = patternParts[1];
|
||
|
var k = '' + regex;
|
||
|
if (!regexKeys.hasOwnProperty(k)) {
|
||
|
allRegexs.push(regex);
|
||
|
regexKeys[k] = null;
|
||
|
}
|
||
|
}
|
||
|
allRegexs.push(/[\0-\uffff]/);
|
||
|
tokenizer = combinePrefixPatterns(allRegexs);
|
||
|
})();
|
||
|
|
||
|
var nPatterns = fallthroughStylePatterns.length;
|
||
|
|
||
|
/**
|
||
|
* Lexes job.sourceCode and produces an output array job.decorations of
|
||
|
* style classes preceded by the position at which they start in
|
||
|
* job.sourceCode in order.
|
||
|
*
|
||
|
* @param {Object} job an object like <pre>{
|
||
|
* sourceCode: {string} sourceText plain text,
|
||
|
* basePos: {int} position of job.sourceCode in the larger chunk of
|
||
|
* sourceCode.
|
||
|
* }</pre>
|
||
|
*/
|
||
|
var decorate = function (job) {
|
||
|
var sourceCode = job.sourceCode, basePos = job.basePos;
|
||
|
/** Even entries are positions in source in ascending order. Odd enties
|
||
|
* are style markers (e.g., PR_COMMENT) that run from that position until
|
||
|
* the end.
|
||
|
* @type {Array.<number|string>}
|
||
|
*/
|
||
|
var decorations = [basePos, PR_PLAIN];
|
||
|
var pos = 0; // index into sourceCode
|
||
|
var tokens = sourceCode.match(tokenizer) || [];
|
||
|
var styleCache = {};
|
||
|
|
||
|
for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
|
||
|
var token = tokens[ti];
|
||
|
var style = styleCache[token];
|
||
|
var match = void 0;
|
||
|
|
||
|
var isEmbedded;
|
||
|
if (typeof style === 'string') {
|
||
|
isEmbedded = false;
|
||
|
} else {
|
||
|
var patternParts = shortcuts[token.charAt(0)];
|
||
|
if (patternParts) {
|
||
|
match = token.match(patternParts[1]);
|
||
|
style = patternParts[0];
|
||
|
} else {
|
||
|
for (var i = 0; i < nPatterns; ++i) {
|
||
|
patternParts = fallthroughStylePatterns[i];
|
||
|
match = token.match(patternParts[1]);
|
||
|
if (match) {
|
||
|
style = patternParts[0];
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!match) { // make sure that we make progress
|
||
|
style = PR_PLAIN;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
|
||
|
if (isEmbedded && !(match && typeof match[1] === 'string')) {
|
||
|
isEmbedded = false;
|
||
|
style = PR_SOURCE;
|
||
|
}
|
||
|
|
||
|
if (!isEmbedded) { styleCache[token] = style; }
|
||
|
}
|
||
|
|
||
|
var tokenStart = pos;
|
||
|
pos += token.length;
|
||
|
|
||
|
if (!isEmbedded) {
|
||
|
decorations.push(basePos + tokenStart, style);
|
||
|
} else { // Treat group 1 as an embedded block of source code.
|
||
|
var embeddedSource = match[1];
|
||
|
var embeddedSourceStart = token.indexOf(embeddedSource);
|
||
|
var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
|
||
|
if (match[2]) {
|
||
|
// If embeddedSource can be blank, then it would match at the
|
||
|
// beginning which would cause us to infinitely recurse on the
|
||
|
// entire token, so we catch the right context in match[2].
|
||
|
embeddedSourceEnd = token.length - match[2].length;
|
||
|
embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
|
||
|
}
|
||
|
var lang = style.substring(5);
|
||
|
// Decorate the left of the embedded source
|
||
|
appendDecorations(
|
||
|
basePos + tokenStart,
|
||
|
token.substring(0, embeddedSourceStart),
|
||
|
decorate, decorations);
|
||
|
// Decorate the embedded source
|
||
|
appendDecorations(
|
||
|
basePos + tokenStart + embeddedSourceStart,
|
||
|
embeddedSource,
|
||
|
langHandlerForExtension(lang, embeddedSource),
|
||
|
decorations);
|
||
|
// Decorate the right of the embedded section
|
||
|
appendDecorations(
|
||
|
basePos + tokenStart + embeddedSourceEnd,
|
||
|
token.substring(embeddedSourceEnd),
|
||
|
decorate, decorations);
|
||
|
}
|
||
|
}
|
||
|
job.decorations = decorations;
|
||
|
};
|
||
|
return decorate;
|
||
|
}
|
||
|
|
||
|
/** returns a function that produces a list of decorations from source text.
|
||
|
*
|
||
|
* This code treats ", ', and ` as string delimiters, and \ as a string
|
||
|
* escape. It does not recognize perl's qq() style strings.
|
||
|
* It has no special handling for double delimiter escapes as in basic, or
|
||
|
* the tripled delimiters used in python, but should work on those regardless
|
||
|
* although in those cases a single string literal may be broken up into
|
||
|
* multiple adjacent string literals.
|
||
|
*
|
||
|
* It recognizes C, C++, and shell style comments.
|
||
|
*
|
||
|
* @param {Object} options a set of optional parameters.
|
||
|
* @return {function (Object)} a function that examines the source code
|
||
|
* in the input job and builds the decoration list.
|
||
|
*/
|
||
|
function sourceDecorator(options) {
|
||
|
var shortcutStylePatterns = [], fallthroughStylePatterns = [];
|
||
|
if (options['tripleQuotedStrings']) {
|
||
|
// '''multi-line-string''', 'single-line-string', and double-quoted
|
||
|
shortcutStylePatterns.push(
|
||
|
[PR_STRING, /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
|
||
|
null, '\'"']);
|
||
|
} else if (options['multiLineStrings']) {
|
||
|
// 'multi-line-string', "multi-line-string"
|
||
|
shortcutStylePatterns.push(
|
||
|
[PR_STRING, /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
|
||
|
null, '\'"`']);
|
||
|
} else {
|
||
|
// 'single-line-string', "single-line-string"
|
||
|
shortcutStylePatterns.push(
|
||
|
[PR_STRING,
|
||
|
/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
|
||
|
null, '"\'']);
|
||
|
}
|
||
|
if (options['verbatimStrings']) {
|
||
|
// verbatim-string-literal production from the C# grammar. See issue 93.
|
||
|
fallthroughStylePatterns.push(
|
||
|
[PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
|
||
|
}
|
||
|
var hc = options['hashComments'];
|
||
|
if (hc) {
|
||
|
if (options['cStyleComments']) {
|
||
|
if (hc > 1) { // multiline hash comments
|
||
|
shortcutStylePatterns.push(
|
||
|
[PR_COMMENT, /^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/, null, '#']);
|
||
|
} else {
|
||
|
// Stop C preprocessor declarations at an unclosed open comment
|
||
|
shortcutStylePatterns.push(
|
||
|
[PR_COMMENT, /^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\r\n]*)/,
|
||
|
null, '#']);
|
||
|
}
|
||
|
// #include <stdio.h>
|
||
|
fallthroughStylePatterns.push(
|
||
|
[PR_STRING,
|
||
|
/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,
|
||
|
null]);
|
||
|
} else {
|
||
|
shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
|
||
|
}
|
||
|
}
|
||
|
if (options['cStyleComments']) {
|
||
|
fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
|
||
|
fallthroughStylePatterns.push(
|
||
|
[PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
|
||
|
}
|
||
|
if (options['regexLiterals']) {
|
||
|
/**
|
||
|
* @const
|
||
|
*/
|
||
|
var REGEX_LITERAL = (
|
||
|
// A regular expression literal starts with a slash that is
|
||
|
// not followed by * or / so that it is not confused with
|
||
|
// comments.
|
||
|
'/(?=[^/*])'
|
||
|
// and then contains any number of raw characters,
|
||
|
+ '(?:[^/\\x5B\\x5C]'
|
||
|
// escape sequences (\x5C),
|
||
|
+ '|\\x5C[\\s\\S]'
|
||
|
// or non-nesting character sets (\x5B\x5D);
|
||
|
+ '|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+'
|
||
|
// finally closed by a /.
|
||
|
+ '/');
|
||
|
fallthroughStylePatterns.push(
|
||
|
['lang-regex',
|
||
|
new RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
|
||
|
]);
|
||
|
}
|
||
|
|
||
|
var types = options['types'];
|
||
|
if (types) {
|
||
|
fallthroughStylePatterns.push([PR_TYPE, types]);
|
||
|
}
|
||
|
|
||
|
var keywords = ("" + options['keywords']).replace(/^ | $/g, '');
|
||
|
if (keywords.length) {
|
||
|
fallthroughStylePatterns.push(
|
||
|
[PR_KEYWORD,
|
||
|
new RegExp('^(?:' + keywords.replace(/[\s,]+/g, '|') + ')\\b'),
|
||
|
null]);
|
||
|
}
|
||
|
|
||
|
shortcutStylePatterns.push([PR_PLAIN, /^\s+/, null, ' \r\n\t\xA0']);
|
||
|
|
||
|
var punctuation =
|
||
|
// The Bash man page says
|
||
|
|
||
|
// A word is a sequence of characters considered as a single
|
||
|
// unit by GRUB. Words are separated by metacharacters,
|
||
|
// which are the following plus space, tab, and newline: { }
|
||
|
// | & $ ; < >
|
||
|
// ...
|
||
|
|
||
|
// A word beginning with # causes that word and all remaining
|
||
|
// characters on that line to be ignored.
|
||
|
|
||
|
// which means that only a '#' after /(?:^|[{}|&$;<>\s])/ starts a
|
||
|
// comment but empirically
|
||
|
// $ echo {#}
|
||
|
// {#}
|
||
|
// $ echo \$#
|
||
|
// $#
|
||
|
// $ echo }#
|
||
|
// }#
|
||
|
|
||
|
// so /(?:^|[|&;<>\s])/ is more appropriate.
|
||
|
|
||
|
// http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC3
|
||
|
// suggests that this definition is compatible with a
|
||
|
// default mode that tries to use a single token definition
|
||
|
// to recognize both bash/python style comments and C
|
||
|
// preprocessor directives.
|
||
|
|
||
|
// This definition of punctuation does not include # in the list of
|
||
|
// follow-on exclusions, so # will not be broken before if preceeded
|
||
|
// by a punctuation character. We could try to exclude # after
|
||
|
// [|&;<>] but that doesn't seem to cause many major problems.
|
||
|
// If that does turn out to be a problem, we should change the below
|
||
|
// when hc is truthy to include # in the run of punctuation characters
|
||
|
// only when not followint [|&;<>].
|
||
|
/^.[^\s\w\.$@\'\"\`\/\\]*/;
|
||
|
|
||
|
fallthroughStylePatterns.push(
|
||
|
// TODO(mikesamuel): recognize non-latin letters and numerals in idents
|
||
|
[PR_LITERAL, /^@[a-z_$][a-z_$@0-9]*/i, null],
|
||
|
[PR_TYPE, /^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/, null],
|
||
|
[PR_PLAIN, /^[a-z_$][a-z_$@0-9]*/i, null],
|
||
|
[PR_LITERAL,
|
||
|
new RegExp(
|
||
|
'^(?:'
|
||
|
// A hex number
|
||
|
+ '0x[a-f0-9]+'
|
||
|
// or an octal or decimal number,
|
||
|
+ '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
|
||
|
// possibly in scientific notation
|
||
|
+ '(?:e[+\\-]?\\d+)?'
|
||
|
+ ')'
|
||
|
// with an optional modifier like UL for unsigned long
|
||
|
+ '[a-z]*', 'i'),
|
||
|
null, '0123456789'],
|
||
|
// Don't treat escaped quotes in bash as starting strings. See issue 144.
|
||
|
[PR_PLAIN, /^\\[\s\S]?/, null],
|
||
|
[PR_PUNCTUATION, punctuation, null]);
|
||
|
|
||
|
return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
|
||
|
}
|
||
|
|
||
|
var decorateSource = sourceDecorator({
|
||
|
'keywords': ALL_KEYWORDS,
|
||
|
'hashComments': true,
|
||
|
'cStyleComments': true,
|
||
|
'multiLineStrings': true,
|
||
|
'regexLiterals': true
|
||
|
});
|
||
|
|
||
|
/**
|
||
|
* Given a DOM subtree, wraps it in a list, and puts each line into its own
|
||
|
* list item.
|
||
|
*
|
||
|
* @param {Node} node modified in place. Its content is pulled into an
|
||
|
* HTMLOListElement, and each line is moved into a separate list item.
|
||
|
* This requires cloning elements, so the input might not have unique
|
||
|
* IDs after numbering.
|
||
|
* @param {boolean} isPreformatted true iff white-space in text nodes should
|
||
|
* be treated as significant.
|
||
|
*/
|
||
|
function numberLines(node, opt_startLineNum, isPreformatted) {
|
||
|
var nocode = /(?:^|\s)nocode(?:\s|$)/;
|
||
|
var lineBreak = /\r\n?|\n/;
|
||
|
|
||
|
var document = node.ownerDocument;
|
||
|
|
||
|
var li = document.createElement('li');
|
||
|
while (node.firstChild) {
|
||
|
li.appendChild(node.firstChild);
|
||
|
}
|
||
|
// An array of lines. We split below, so this is initialized to one
|
||
|
// un-split line.
|
||
|
var listItems = [li];
|
||
|
|
||
|
function walk(node) {
|
||
|
switch (node.nodeType) {
|
||
|
case 1: // Element
|
||
|
if (nocode.test(node.className)) { break; }
|
||
|
if ('br' === node.nodeName) {
|
||
|
breakAfter(node);
|
||
|
// Discard the <BR> since it is now flush against a </LI>.
|
||
|
if (node.parentNode) {
|
||
|
node.parentNode.removeChild(node);
|
||
|
}
|
||
|
} else {
|
||
|
for (var child = node.firstChild; child; child = child.nextSibling) {
|
||
|
walk(child);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case 3: case 4: // Text
|
||
|
if (isPreformatted) {
|
||
|
var text = node.nodeValue;
|
||
|
var match = text.match(lineBreak);
|
||
|
if (match) {
|
||
|
var firstLine = text.substring(0, match.index);
|
||
|
node.nodeValue = firstLine;
|
||
|
var tail = text.substring(match.index + match[0].length);
|
||
|
if (tail) {
|
||
|
var parent = node.parentNode;
|
||
|
parent.insertBefore(
|
||
|
document.createTextNode(tail), node.nextSibling);
|
||
|
}
|
||
|
breakAfter(node);
|
||
|
if (!firstLine) {
|
||
|
// Don't leave blank text nodes in the DOM.
|
||
|
node.parentNode.removeChild(node);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Split a line after the given node.
|
||
|
function breakAfter(lineEndNode) {
|
||
|
// If there's nothing to the right, then we can skip ending the line
|
||
|
// here, and move root-wards since splitting just before an end-tag
|
||
|
// would require us to create a bunch of empty copies.
|
||
|
while (!lineEndNode.nextSibling) {
|
||
|
lineEndNode = lineEndNode.parentNode;
|
||
|
if (!lineEndNode) { return; }
|
||
|
}
|
||
|
|
||
|
function breakLeftOf(limit, copy) {
|
||
|
// Clone shallowly if this node needs to be on both sides of the break.
|
||
|
var rightSide = copy ? limit.cloneNode(false) : limit;
|
||
|
var parent = limit.parentNode;
|
||
|
if (parent) {
|
||
|
// We clone the parent chain.
|
||
|
// This helps us resurrect important styling elements that cross lines.
|
||
|
// E.g. in <i>Foo<br>Bar</i>
|
||
|
// should be rewritten to <li><i>Foo</i></li><li><i>Bar</i></li>.
|
||
|
var parentClone = breakLeftOf(parent, 1);
|
||
|
// Move the clone and everything to the right of the original
|
||
|
// onto the cloned parent.
|
||
|
var next = limit.nextSibling;
|
||
|
parentClone.appendChild(rightSide);
|
||
|
for (var sibling = next; sibling; sibling = next) {
|
||
|
next = sibling.nextSibling;
|
||
|
parentClone.appendChild(sibling);
|
||
|
}
|
||
|
}
|
||
|
return rightSide;
|
||
|
}
|
||
|
|
||
|
var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0);
|
||
|
|
||
|
// Walk the parent chain until we reach an unattached LI.
|
||
|
for (var parent;
|
||
|
// Check nodeType since IE invents document fragments.
|
||
|
(parent = copiedListItem.parentNode) && parent.nodeType === 1;) {
|
||
|
copiedListItem = parent;
|
||
|
}
|
||
|
// Put it on the list of lines for later processing.
|
||
|
listItems.push(copiedListItem);
|
||
|
}
|
||
|
|
||
|
// Split lines while there are lines left to split.
|
||
|
for (var i = 0; // Number of lines that have been split so far.
|
||
|
i < listItems.length; // length updated by breakAfter calls.
|
||
|
++i) {
|
||
|
walk(listItems[i]);
|
||
|
}
|
||
|
|
||
|
// Make sure numeric indices show correctly.
|
||
|
if (opt_startLineNum === (opt_startLineNum|0)) {
|
||
|
listItems[0].setAttribute('value', opt_startLineNum);
|
||
|
}
|
||
|
|
||
|
var ol = document.createElement('ol');
|
||
|
ol.className = 'linenums';
|
||
|
var offset = Math.max(0, ((opt_startLineNum - 1 /* zero index */)) | 0) || 0;
|
||
|
for (var i = 0, n = listItems.length; i < n; ++i) {
|
||
|
li = listItems[i];
|
||
|
// Stick a class on the LIs so that stylesheets can
|
||
|
// color odd/even rows, or any other row pattern that
|
||
|
// is co-prime with 10.
|
||
|
li.className = 'L' + ((i + offset) % 10);
|
||
|
if (!li.firstChild) {
|
||
|
li.appendChild(document.createTextNode('\xA0'));
|
||
|
}
|
||
|
ol.appendChild(li);
|
||
|
}
|
||
|
|
||
|
node.appendChild(ol);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Breaks {@code job.sourceCode} around style boundaries in
|
||
|
* {@code job.decorations} and modifies {@code job.sourceNode} in place.
|
||
|
* @param {Object} job like <pre>{
|
||
|
* sourceCode: {string} source as plain text,
|
||
|
* spans: {Array.<number|Node>} alternating span start indices into source
|
||
|
* and the text node or element (e.g. {@code <BR>}) corresponding to that
|
||
|
* span.
|
||
|
* decorations: {Array.<number|string} an array of style classes preceded
|
||
|
* by the position at which they start in job.sourceCode in order
|
||
|
* }</pre>
|
||
|
* @private
|
||
|
*/
|
||
|
function recombineTagsAndDecorations(job) {
|
||
|
var isIE8OrEarlier = /\bMSIE\s(\d+)/.exec(navigator.userAgent);
|
||
|
isIE8OrEarlier = isIE8OrEarlier && +isIE8OrEarlier[1] <= 8;
|
||
|
var newlineRe = /\n/g;
|
||
|
|
||
|
var source = job.sourceCode;
|
||
|
var sourceLength = source.length;
|
||
|
// Index into source after the last code-unit recombined.
|
||
|
var sourceIndex = 0;
|
||
|
|
||
|
var spans = job.spans;
|
||
|
var nSpans = spans.length;
|
||
|
// Index into spans after the last span which ends at or before sourceIndex.
|
||
|
var spanIndex = 0;
|
||
|
|
||
|
var decorations = job.decorations;
|
||
|
var nDecorations = decorations.length;
|
||
|
// Index into decorations after the last decoration which ends at or before
|
||
|
// sourceIndex.
|
||
|
var decorationIndex = 0;
|
||
|
|
||
|
// Remove all zero-length decorations.
|
||
|
decorations[nDecorations] = sourceLength;
|
||
|
var decPos, i;
|
||
|
for (i = decPos = 0; i < nDecorations;) {
|
||
|
if (decorations[i] !== decorations[i + 2]) {
|
||
|
decorations[decPos++] = decorations[i++];
|
||
|
decorations[decPos++] = decorations[i++];
|
||
|
} else {
|
||
|
i += 2;
|
||
|
}
|
||
|
}
|
||
|
nDecorations = decPos;
|
||
|
|
||
|
// Simplify decorations.
|
||
|
for (i = decPos = 0; i < nDecorations;) {
|
||
|
var startPos = decorations[i];
|
||
|
// Conflate all adjacent decorations that use the same style.
|
||
|
var startDec = decorations[i + 1];
|
||
|
var end = i + 2;
|
||
|
while (end + 2 <= nDecorations && decorations[end + 1] === startDec) {
|
||
|
end += 2;
|
||
|
}
|
||
|
decorations[decPos++] = startPos;
|
||
|
decorations[decPos++] = startDec;
|
||
|
i = end;
|
||
|
}
|
||
|
|
||
|
nDecorations = decorations.length = decPos;
|
||
|
|
||
|
var sourceNode = job.sourceNode;
|
||
|
var oldDisplay;
|
||
|
if (sourceNode) {
|
||
|
oldDisplay = sourceNode.style.display;
|
||
|
sourceNode.style.display = 'none';
|
||
|
}
|
||
|
try {
|
||
|
var decoration = null;
|
||
|
while (spanIndex < nSpans) {
|
||
|
var spanStart = spans[spanIndex];
|
||
|
var spanEnd = spans[spanIndex + 2] || sourceLength;
|
||
|
|
||
|
var decEnd = decorations[decorationIndex + 2] || sourceLength;
|
||
|
|
||
|
var end = Math.min(spanEnd, decEnd);
|
||
|
|
||
|
var textNode = spans[spanIndex + 1];
|
||
|
var styledText;
|
||
|
if (textNode.nodeType !== 1 // Don't muck with <BR>s or <LI>s
|
||
|
// Don't introduce spans around empty text nodes.
|
||
|
&& (styledText = source.substring(sourceIndex, end))) {
|
||
|
// This may seem bizarre, and it is. Emitting LF on IE causes the
|
||
|
// code to display with spaces instead of line breaks.
|
||
|
// Emitting Windows standard issue linebreaks (CRLF) causes a blank
|
||
|
// space to appear at the beginning of every line but the first.
|
||
|
// Emitting an old Mac OS 9 line separator makes everything spiffy.
|
||
|
if (isIE8OrEarlier) {
|
||
|
styledText = styledText.replace(newlineRe, '\r');
|
||
|
}
|
||
|
textNode.nodeValue = styledText;
|
||
|
var document = textNode.ownerDocument;
|
||
|
var span = document.createElement('span');
|
||
|
span.className = decorations[decorationIndex + 1];
|
||
|
var parentNode = textNode.parentNode;
|
||
|
parentNode.replaceChild(span, textNode);
|
||
|
span.appendChild(textNode);
|
||
|
if (sourceIndex < spanEnd) { // Split off a text node.
|
||
|
spans[spanIndex + 1] = textNode
|
||
|
// TODO: Possibly optimize by using '' if there's no flicker.
|
||
|
= document.createTextNode(source.substring(end, spanEnd));
|
||
|
parentNode.insertBefore(textNode, span.nextSibling);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
sourceIndex = end;
|
||
|
|
||
|
if (sourceIndex >= spanEnd) {
|
||
|
spanIndex += 2;
|
||
|
}
|
||
|
if (sourceIndex >= decEnd) {
|
||
|
decorationIndex += 2;
|
||
|
}
|
||
|
}
|
||
|
} finally {
|
||
|
if (sourceNode) {
|
||
|
sourceNode.style.display = oldDisplay;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/** Maps language-specific file extensions to handlers. */
|
||
|
var langHandlerRegistry = {};
|
||
|
/** Register a language handler for the given file extensions.
|
||
|
* @param {function (Object)} handler a function from source code to a list
|
||
|
* of decorations. Takes a single argument job which describes the
|
||
|
* state of the computation. The single parameter has the form
|
||
|
* {@code {
|
||
|
* sourceCode: {string} as plain text.
|
||
|
* decorations: {Array.<number|string>} an array of style classes
|
||
|
* preceded by the position at which they start in
|
||
|
* job.sourceCode in order.
|
||
|
* The language handler should assigned this field.
|
||
|
* basePos: {int} the position of source in the larger source chunk.
|
||
|
* All positions in the output decorations array are relative
|
||
|
* to the larger source chunk.
|
||
|
* } }
|
||
|
* @param {Array.<string>} fileExtensions
|
||
|
*/
|
||
|
function registerLangHandler(handler, fileExtensions) {
|
||
|
for (var i = fileExtensions.length; --i >= 0;) {
|
||
|
var ext = fileExtensions[i];
|
||
|
if (!langHandlerRegistry.hasOwnProperty(ext)) {
|
||
|
langHandlerRegistry[ext] = handler;
|
||
|
} else if (win['console']) {
|
||
|
console['warn']('cannot override language handler %s', ext);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
function langHandlerForExtension(extension, source) {
|
||
|
if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
|
||
|
// Treat it as markup if the first non whitespace character is a < and
|
||
|
// the last non-whitespace character is a >.
|
||
|
extension = /^\s*</.test(source)
|
||
|
? 'default-markup'
|
||
|
: 'default-code';
|
||
|
}
|
||
|
return langHandlerRegistry[extension];
|
||
|
}
|
||
|
registerLangHandler(decorateSource, ['default-code']);
|
||
|
registerLangHandler(
|
||
|
createSimpleLexer(
|
||
|
[],
|
||
|
[
|
||
|
[PR_PLAIN, /^[^<?]+/],
|
||
|
[PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
|
||
|
[PR_COMMENT, /^<\!--[\s\S]*?(?:-\->|$)/],
|
||
|
// Unescaped content in an unknown language
|
||
|
['lang-', /^<\?([\s\S]+?)(?:\?>|$)/],
|
||
|
['lang-', /^<%([\s\S]+?)(?:%>|$)/],
|
||
|
[PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
|
||
|
['lang-', /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
|
||
|
// Unescaped content in javascript. (Or possibly vbscript).
|
||
|
['lang-js', /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
|
||
|
// Contains unescaped stylesheet content
|
||
|
['lang-css', /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
|
||
|
['lang-in.tag', /^(<\/?[a-z][^<>]*>)/i]
|
||
|
]),
|
||
|
['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
|
||
|
registerLangHandler(
|
||
|
createSimpleLexer(
|
||
|
[
|
||
|
[PR_PLAIN, /^[\s]+/, null, ' \t\r\n'],
|
||
|
[PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
|
||
|
],
|
||
|
[
|
||
|
[PR_TAG, /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
|
||
|
[PR_ATTRIB_NAME, /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
|
||
|
['lang-uq.val', /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
|
||
|
[PR_PUNCTUATION, /^[=<>\/]+/],
|
||
|
['lang-js', /^on\w+\s*=\s*\"([^\"]+)\"/i],
|
||
|
['lang-js', /^on\w+\s*=\s*\'([^\']+)\'/i],
|
||
|
['lang-js', /^on\w+\s*=\s*([^\"\'>\s]+)/i],
|
||
|
['lang-css', /^style\s*=\s*\"([^\"]+)\"/i],
|
||
|
['lang-css', /^style\s*=\s*\'([^\']+)\'/i],
|
||
|
['lang-css', /^style\s*=\s*([^\"\'>\s]+)/i]
|
||
|
]),
|
||
|
['in.tag']);
|
||
|
registerLangHandler(
|
||
|
createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
|
||
|
registerLangHandler(sourceDecorator({
|
||
|
'keywords': CPP_KEYWORDS,
|
||
|
'hashComments': true,
|
||
|
'cStyleComments': true,
|
||
|
'types': C_TYPES
|
||
|
}), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
|
||
|
registerLangHandler(sourceDecorator({
|
||
|
'keywords': 'null,true,false'
|
||
|
}), ['json']);
|
||
|
registerLangHandler(sourceDecorator({
|
||
|
'keywords': CSHARP_KEYWORDS,
|
||
|
'hashComments': true,
|
||
|
'cStyleComments': true,
|
||
|
'verbatimStrings': true,
|
||
|
'types': C_TYPES
|
||
|
}), ['cs']);
|
||
|
registerLangHandler(sourceDecorator({
|
||
|
'keywords': JAVA_KEYWORDS,
|
||
|
'cStyleComments': true
|
||
|
}), ['java']);
|
||
|
registerLangHandler(sourceDecorator({
|
||
|
'keywords': SH_KEYWORDS,
|
||
|
'hashComments': true,
|
||
|
'multiLineStrings': true
|
||
|
}), ['bsh', 'csh', 'sh']);
|
||
|
registerLangHandler(sourceDecorator({
|
||
|
'keywords': PYTHON_KEYWORDS,
|
||
|
'hashComments': true,
|
||
|
'multiLineStrings': true,
|
||
|
'tripleQuotedStrings': true
|
||
|
}), ['cv', 'py']);
|
||
|
registerLangHandler(sourceDecorator({
|
||
|
'keywords': PERL_KEYWORDS,
|
||
|
'hashComments': true,
|
||
|
'multiLineStrings': true,
|
||
|
'regexLiterals': true
|
||
|
}), ['perl', 'pl', 'pm']);
|
||
|
registerLangHandler(sourceDecorator({
|
||
|
'keywords': RUBY_KEYWORDS,
|
||
|
'hashComments': true,
|
||
|
'multiLineStrings': true,
|
||
|
'regexLiterals': true
|
||
|
}), ['rb']);
|
||
|
registerLangHandler(sourceDecorator({
|
||
|
'keywords': JSCRIPT_KEYWORDS,
|
||
|
'cStyleComments': true,
|
||
|
'regexLiterals': true
|
||
|
}), ['js']);
|
||
|
registerLangHandler(sourceDecorator({
|
||
|
'keywords': COFFEE_KEYWORDS,
|
||
|
'hashComments': 3, // ### style block comments
|
||
|
'cStyleComments': true,
|
||
|
'multilineStrings': true,
|
||
|
'tripleQuotedStrings': true,
|
||
|
'regexLiterals': true
|
||
|
}), ['coffee']);
|
||
|
registerLangHandler(
|
||
|
createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
|
||
|
|
||
|
function applyDecorator(job) {
|
||
|
var opt_langExtension = job.langExtension;
|
||
|
|
||
|
try {
|
||
|
// Extract tags, and convert the source code to plain text.
|
||
|
var sourceAndSpans = extractSourceSpans(job.sourceNode, job.pre);
|
||
|
/** Plain text. @type {string} */
|
||
|
var source = sourceAndSpans.sourceCode;
|
||
|
job.sourceCode = source;
|
||
|
job.spans = sourceAndSpans.spans;
|
||
|
job.basePos = 0;
|
||
|
|
||
|
// Apply the appropriate language handler
|
||
|
langHandlerForExtension(opt_langExtension, source)(job);
|
||
|
|
||
|
// Integrate the decorations and tags back into the source code,
|
||
|
// modifying the sourceNode in place.
|
||
|
recombineTagsAndDecorations(job);
|
||
|
} catch (e) {
|
||
|
if (win['console']) {
|
||
|
console['log'](e && e['stack'] ? e['stack'] : e);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param sourceCodeHtml {string} The HTML to pretty print.
|
||
|
* @param opt_langExtension {string} The language name to use.
|
||
|
* Typically, a filename extension like 'cpp' or 'java'.
|
||
|
* @param opt_numberLines {number|boolean} True to number lines,
|
||
|
* or the 1-indexed number of the first line in sourceCodeHtml.
|
||
|
*/
|
||
|
function prettyPrintOne(sourceCodeHtml, opt_langExtension, opt_numberLines) {
|
||
|
var container = document.createElement('pre');
|
||
|
// This could cause images to load and onload listeners to fire.
|
||
|
// E.g. <img onerror="alert(1337)" src="nosuchimage.png">.
|
||
|
// We assume that the inner HTML is from a trusted source.
|
||
|
container.innerHTML = sourceCodeHtml;
|
||
|
if (opt_numberLines) {
|
||
|
numberLines(container, opt_numberLines, true);
|
||
|
}
|
||
|
|
||
|
var job = {
|
||
|
langExtension: opt_langExtension,
|
||
|
numberLines: opt_numberLines,
|
||
|
sourceNode: container,
|
||
|
pre: 1
|
||
|
};
|
||
|
applyDecorator(job);
|
||
|
return container.innerHTML;
|
||
|
}
|
||
|
|
||
|
function prettyPrint(opt_whenDone) {
|
||
|
function byTagName(tn) { return document.getElementsByTagName(tn); }
|
||
|
// fetch a list of nodes to rewrite
|
||
|
var codeSegments = [byTagName('pre'), byTagName('code'), byTagName('xmp')];
|
||
|
var elements = [];
|
||
|
for (var i = 0; i < codeSegments.length; ++i) {
|
||
|
for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
|
||
|
elements.push(codeSegments[i][j]);
|
||
|
}
|
||
|
}
|
||
|
codeSegments = null;
|
||
|
|
||
|
var clock = Date;
|
||
|
if (!clock['now']) {
|
||
|
clock = { 'now': function () { return +(new Date); } };
|
||
|
}
|
||
|
|
||
|
// The loop is broken into a series of continuations to make sure that we
|
||
|
// don't make the browser unresponsive when rewriting a large page.
|
||
|
var k = 0;
|
||
|
var prettyPrintingJob;
|
||
|
|
||
|
var langExtensionRe = /\blang(?:uage)?-([\w.]+)(?!\S)/;
|
||
|
var prettyPrintRe = /\bprettyprint\b/;
|
||
|
var prettyPrintedRe = /\bprettyprinted\b/;
|
||
|
var preformattedTagNameRe = /pre|xmp/i;
|
||
|
var codeRe = /^code$/i;
|
||
|
var preCodeXmpRe = /^(?:pre|code|xmp)$/i;
|
||
|
|
||
|
function doWork() {
|
||
|
var endTime = (win['PR_SHOULD_USE_CONTINUATION'] ?
|
||
|
clock['now']() + 250 /* ms */ :
|
||
|
Infinity);
|
||
|
for (; k < elements.length && clock['now']() < endTime; k++) {
|
||
|
var cs = elements[k];
|
||
|
var className = cs.className;
|
||
|
if (prettyPrintRe.test(className)
|
||
|
// Don't redo this if we've already done it.
|
||
|
// This allows recalling pretty print to just prettyprint elements
|
||
|
// that have been added to the page since last call.
|
||
|
&& !prettyPrintedRe.test(className)) {
|
||
|
|
||
|
// make sure this is not nested in an already prettified element
|
||
|
var nested = false;
|
||
|
for (var p = cs.parentNode; p; p = p.parentNode) {
|
||
|
var tn = p.tagName;
|
||
|
if (preCodeXmpRe.test(tn)
|
||
|
&& p.className && prettyPrintRe.test(p.className)) {
|
||
|
nested = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (!nested) {
|
||
|
// Mark done. If we fail to prettyprint for whatever reason,
|
||
|
// we shouldn't try again.
|
||
|
cs.className += ' prettyprinted';
|
||
|
|
||
|
// If the classes includes a language extensions, use it.
|
||
|
// Language extensions can be specified like
|
||
|
// <pre class="prettyprint lang-cpp">
|
||
|
// the language extension "cpp" is used to find a language handler
|
||
|
// as passed to PR.registerLangHandler.
|
||
|
// HTML5 recommends that a language be specified using "language-"
|
||
|
// as the prefix instead. Google Code Prettify supports both.
|
||
|
// http://dev.w3.org/html5/spec-author-view/the-code-element.html
|
||
|
var langExtension = className.match(langExtensionRe);
|
||
|
// Support <pre class="prettyprint"><code class="language-c">
|
||
|
var wrapper;
|
||
|
if (!langExtension && (wrapper = childContentWrapper(cs))
|
||
|
&& codeRe.test(wrapper.tagName)) {
|
||
|
langExtension = wrapper.className.match(langExtensionRe);
|
||
|
}
|
||
|
|
||
|
if (langExtension) { langExtension = langExtension[1]; }
|
||
|
|
||
|
var preformatted;
|
||
|
if (preformattedTagNameRe.test(cs.tagName)) {
|
||
|
preformatted = 1;
|
||
|
} else {
|
||
|
var currentStyle = cs['currentStyle'];
|
||
|
var whitespace = (
|
||
|
currentStyle
|
||
|
? currentStyle['whiteSpace']
|
||
|
: (document.defaultView
|
||
|
&& document.defaultView.getComputedStyle)
|
||
|
? document.defaultView.getComputedStyle(cs, null)
|
||
|
.getPropertyValue('white-space')
|
||
|
: 0);
|
||
|
preformatted = whitespace
|
||
|
&& 'pre' === whitespace.substring(0, 3);
|
||
|
}
|
||
|
|
||
|
// Look for a class like linenums or linenums:<n> where <n> is the
|
||
|
// 1-indexed number of the first line.
|
||
|
var lineNums = cs.className.match(/\blinenums\b(?::(\d+))?/);
|
||
|
lineNums = lineNums
|
||
|
? lineNums[1] && lineNums[1].length ? +lineNums[1] : true
|
||
|
: false;
|
||
|
if (lineNums) { numberLines(cs, lineNums, preformatted); }
|
||
|
|
||
|
// do the pretty printing
|
||
|
prettyPrintingJob = {
|
||
|
langExtension: langExtension,
|
||
|
sourceNode: cs,
|
||
|
numberLines: lineNums,
|
||
|
pre: preformatted
|
||
|
};
|
||
|
applyDecorator(prettyPrintingJob);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (k < elements.length) {
|
||
|
// finish up in a continuation
|
||
|
setTimeout(doWork, 250);
|
||
|
} else if (opt_whenDone) {
|
||
|
opt_whenDone();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
doWork();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Contains functions for creating and registering new language handlers.
|
||
|
* @type {Object}
|
||
|
*/
|
||
|
var PR = win['PR'] = {
|
||
|
'createSimpleLexer': createSimpleLexer,
|
||
|
'registerLangHandler': registerLangHandler,
|
||
|
'sourceDecorator': sourceDecorator,
|
||
|
'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
|
||
|
'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
|
||
|
'PR_COMMENT': PR_COMMENT,
|
||
|
'PR_DECLARATION': PR_DECLARATION,
|
||
|
'PR_KEYWORD': PR_KEYWORD,
|
||
|
'PR_LITERAL': PR_LITERAL,
|
||
|
'PR_NOCODE': PR_NOCODE,
|
||
|
'PR_PLAIN': PR_PLAIN,
|
||
|
'PR_PUNCTUATION': PR_PUNCTUATION,
|
||
|
'PR_SOURCE': PR_SOURCE,
|
||
|
'PR_STRING': PR_STRING,
|
||
|
'PR_TAG': PR_TAG,
|
||
|
'PR_TYPE': PR_TYPE,
|
||
|
'prettyPrintOne': win['prettyPrintOne'] = prettyPrintOne,
|
||
|
'prettyPrint': win['prettyPrint'] = prettyPrint
|
||
|
};
|
||
|
|
||
|
// Make PR available via the Asynchronous Module Definition (AMD) API.
|
||
|
// Per https://github.com/amdjs/amdjs-api/wiki/AMD:
|
||
|
// The Asynchronous Module Definition (AMD) API specifies a
|
||
|
// mechanism for defining modules such that the module and its
|
||
|
// dependencies can be asynchronously loaded.
|
||
|
// ...
|
||
|
// To allow a clear indicator that a global define function (as
|
||
|
// needed for script src browser loading) conforms to the AMD API,
|
||
|
// any global define function SHOULD have a property called "amd"
|
||
|
// whose value is an object. This helps avoid conflict with any
|
||
|
// other existing JavaScript code that could have defined a define()
|
||
|
// function that does not conform to the AMD API.
|
||
|
if (typeof define === "function" && define['amd']) {
|
||
|
define(function () {
|
||
|
return PR;
|
||
|
});
|
||
|
}
|
||
|
})();
|
||
|
</script>
|
||
|
|
||
|
<script>(function(scope) {
|
||
|
|
||
|
var ContextFreeParser = {
|
||
|
parse: function(text) {
|
||
|
var top = {};
|
||
|
var entities = [];
|
||
|
var current = top;
|
||
|
var subCurrent = {};
|
||
|
|
||
|
var scriptDocCommentClause = '\\/\\*\\*([\\s\\S]*?)\\*\\/';
|
||
|
var htmlDocCommentClause = '<!--([\\s\\S]*?)-->';
|
||
|
|
||
|
// matches text between /** and */ inclusive and <!-- and --> inclusive
|
||
|
var docCommentRegex = new RegExp(scriptDocCommentClause + '|' + htmlDocCommentClause, 'g');
|
||
|
|
||
|
// acquire all script doc comments
|
||
|
var docComments = text.match(docCommentRegex) || [];
|
||
|
|
||
|
// each match represents a single block of doc comments
|
||
|
docComments.forEach(function(m) {
|
||
|
// unify line ends, remove all comment characters, split into individual lines
|
||
|
var lines = m.replace(/\r\n/g, '\n').replace(/^\s*\/\*\*|^\s*\*\/|^\s*\* ?|^\s*\<\!-\-|^s*\-\-\>/gm, '').split('\n');
|
||
|
|
||
|
// pragmas (@-rules) must occur on a line by themselves
|
||
|
var pragmas = [];
|
||
|
// filter lines whose first non-whitespace character is @ into the pragma list
|
||
|
// (and out of the `lines` array)
|
||
|
lines = lines.filter(function(l) {
|
||
|
var m = l.match(/\s*@([\w-]*) (.*)/);
|
||
|
if (!m) {
|
||
|
return true;
|
||
|
}
|
||
|
pragmas.push(m);
|
||
|
});
|
||
|
|
||
|
// collect all other text into a single block
|
||
|
var code = lines.join('\n');
|
||
|
|
||
|
// process pragmas
|
||
|
pragmas.forEach(function(m) {
|
||
|
var pragma = m[1], content = m[2];
|
||
|
switch (pragma) {
|
||
|
|
||
|
// currently all entities are either @class or @element
|
||
|
case 'class':
|
||
|
case 'element':
|
||
|
current = {
|
||
|
name: content,
|
||
|
description: code
|
||
|
};
|
||
|
entities.push(current);
|
||
|
break;
|
||
|
|
||
|
// an entity may have these describable sub-features
|
||
|
case 'attribute':
|
||
|
case 'property':
|
||
|
case 'method':
|
||
|
case 'event':
|
||
|
subCurrent = {
|
||
|
name: content,
|
||
|
description: code
|
||
|
};
|
||
|
var label = pragma == 'property' ? 'properties' : pragma + 's';
|
||
|
makePragma(current, label, subCurrent);
|
||
|
break;
|
||
|
|
||
|
// sub-feature pragmas
|
||
|
case 'default':
|
||
|
case 'type':
|
||
|
subCurrent[pragma] = content;
|
||
|
break;
|
||
|
|
||
|
// everything else
|
||
|
default:
|
||
|
current[pragma] = content;
|
||
|
break;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// utility function, yay hoisting
|
||
|
function makePragma(object, pragma, content) {
|
||
|
var p$ = object;
|
||
|
var p = p$[pragma];
|
||
|
if (!p) {
|
||
|
p$[pragma] = p = [];
|
||
|
}
|
||
|
p.push(content);
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
if (entities.length === 0) {
|
||
|
entities.push({name: 'Entity', description: '**Undocumented**'});
|
||
|
}
|
||
|
return entities;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
if (typeof module !== 'undefined' && module.exports) {
|
||
|
module.exports = ContextFreeParser;
|
||
|
} else {
|
||
|
scope.ContextFreeParser = ContextFreeParser;
|
||
|
}
|
||
|
|
||
|
})(this);</script>
|
||
|
<!--
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
-->
|
||
|
|
||
|
<!--
|
||
|
@group Polymer Core Elements
|
||
|
|
||
|
The `core-ajax` element exposes `XMLHttpRequest` functionality.
|
||
|
|
||
|
<core-ajax
|
||
|
auto
|
||
|
url="http://gdata.youtube.com/feeds/api/videos/"
|
||
|
params='{"alt":"json", "q":"chrome"}'
|
||
|
handleAs="json"
|
||
|
on-core-response="{{handleResponse}}"></core-ajax>
|
||
|
|
||
|
With `auto` set to `true`, the element performs a request whenever
|
||
|
its `url` or `params` properties are changed.
|
||
|
|
||
|
Note: The `params` attribute must be double quoted JSON.
|
||
|
|
||
|
You can trigger a request explicitly by calling `go` on the
|
||
|
element.
|
||
|
|
||
|
@element core-ajax
|
||
|
@status beta
|
||
|
@homepage github.io
|
||
|
-->
|
||
|
<!--
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
-->
|
||
|
<!--
|
||
|
/**
|
||
|
* @group Polymer Core Elements
|
||
|
*
|
||
|
* core-xhr can be used to perform XMLHttpRequests.
|
||
|
*
|
||
|
* <core-xhr id="xhr"></core-xhr>
|
||
|
* ...
|
||
|
* this.$.xhr.request({url: url, params: params, callback: callback});
|
||
|
*
|
||
|
* @element core-xhr
|
||
|
*/
|
||
|
-->
|
||
|
|
||
|
|
||
|
|
||
|
<polymer-element name="core-xhr" hidden assetpath="../core-ajax/">
|
||
|
|
||
|
<script>
|
||
|
|
||
|
Polymer('core-xhr', {
|
||
|
|
||
|
/**
|
||
|
* Sends a HTTP request to the server and returns the XHR object.
|
||
|
*
|
||
|
* @method request
|
||
|
* @param {Object} inOptions
|
||
|
* @param {String} inOptions.url The url to which the request is sent.
|
||
|
* @param {String} inOptions.method The HTTP method to use, default is GET.
|
||
|
* @param {boolean} inOptions.sync By default, all requests are sent asynchronously. To send synchronous requests, set to true.
|
||
|
* @param {Object} inOptions.params Data to be sent to the server.
|
||
|
* @param {Object} inOptions.body The content for the request body for POST method.
|
||
|
* @param {Object} inOptions.headers HTTP request headers.
|
||
|
* @param {String} inOptions.responseType The response type. Default is 'text'.
|
||
|
* @param {boolean} inOptions.withCredentials Whether or not to send credentials on the request. Default is false.
|
||
|
* @param {Object} inOptions.callback Called when request is completed.
|
||
|
* @returns {Object} XHR object.
|
||
|
*/
|
||
|
request: function(options) {
|
||
|
var xhr = new XMLHttpRequest();
|
||
|
var url = options.url;
|
||
|
var method = options.method || 'GET';
|
||
|
var async = !options.sync;
|
||
|
//
|
||
|
var params = this.toQueryString(options.params);
|
||
|
if (params && method == 'GET') {
|
||
|
url += (url.indexOf('?') > 0 ? '&' : '?') + params;
|
||
|
}
|
||
|
var xhrParams = this.isBodyMethod(method) ? (options.body || params) : null;
|
||
|
//
|
||
|
xhr.open(method, url, async);
|
||
|
if (options.responseType) {
|
||
|
xhr.responseType = options.responseType;
|
||
|
}
|
||
|
if (options.withCredentials) {
|
||
|
xhr.withCredentials = true;
|
||
|
}
|
||
|
this.makeReadyStateHandler(xhr, options.callback);
|
||
|
this.setRequestHeaders(xhr, options.headers);
|
||
|
xhr.send(xhrParams);
|
||
|
if (!async) {
|
||
|
xhr.onreadystatechange(xhr);
|
||
|
}
|
||
|
return xhr;
|
||
|
},
|
||
|
|
||
|
toQueryString: function(params) {
|
||
|
var r = [];
|
||
|
for (var n in params) {
|
||
|
var v = params[n];
|
||
|
n = encodeURIComponent(n);
|
||
|
r.push(v == null ? n : (n + '=' + encodeURIComponent(v)));
|
||
|
}
|
||
|
return r.join('&');
|
||
|
},
|
||
|
|
||
|
isBodyMethod: function(method) {
|
||
|
return this.bodyMethods[(method || '').toUpperCase()];
|
||
|
},
|
||
|
|
||
|
bodyMethods: {
|
||
|
POST: 1,
|
||
|
PUT: 1,
|
||
|
DELETE: 1
|
||
|
},
|
||
|
|
||
|
makeReadyStateHandler: function(xhr, callback) {
|
||
|
xhr.onreadystatechange = function() {
|
||
|
if (xhr.readyState == 4) {
|
||
|
callback && callback.call(null, xhr.response, xhr);
|
||
|
}
|
||
|
};
|
||
|
},
|
||
|
|
||
|
setRequestHeaders: function(xhr, headers) {
|
||
|
if (headers) {
|
||
|
for (var name in headers) {
|
||
|
xhr.setRequestHeader(name, headers[name]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
</script>
|
||
|
|
||
|
</polymer-element>
|
||
|
|
||
|
<polymer-element name="core-ajax" attributes="url handleAs auto params response method headers body contentType withCredentials" assetpath="../core-ajax/">
|
||
|
<script>
|
||
|
|
||
|
Polymer('core-ajax', {
|
||
|
/**
|
||
|
* Fired when a response is received.
|
||
|
*
|
||
|
* @event core-response
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* Fired when an error is received.
|
||
|
*
|
||
|
* @event core-error
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* Fired whenever a response or an error is received.
|
||
|
*
|
||
|
* @event core-complete
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* The URL target of the request.
|
||
|
*
|
||
|
* @attribute url
|
||
|
* @type string
|
||
|
* @default ''
|
||
|
*/
|
||
|
url: '',
|
||
|
|
||
|
/**
|
||
|
* Specifies what data to store in the `response` property, and
|
||
|
* to deliver as `event.response` in `response` events.
|
||
|
*
|
||
|
* One of:
|
||
|
*
|
||
|
* `text`: uses `XHR.responseText`.
|
||
|
*
|
||
|
* `xml`: uses `XHR.responseXML`.
|
||
|
*
|
||
|
* `json`: uses `XHR.responseText` parsed as JSON.
|
||
|
*
|
||
|
* `arraybuffer`: uses `XHR.response`.
|
||
|
*
|
||
|
* `blob`: uses `XHR.response`.
|
||
|
*
|
||
|
* `document`: uses `XHR.response`.
|
||
|
*
|
||
|
* @attribute handleAs
|
||
|
* @type string
|
||
|
* @default 'text'
|
||
|
*/
|
||
|
handleAs: '',
|
||
|
|
||
|
/**
|
||
|
* If true, automatically performs an Ajax request when either `url` or `params` changes.
|
||
|
*
|
||
|
* @attribute auto
|
||
|
* @type boolean
|
||
|
* @default false
|
||
|
*/
|
||
|
auto: false,
|
||
|
|
||
|
/**
|
||
|
* Parameters to send to the specified URL, as JSON.
|
||
|
*
|
||
|
* @attribute params
|
||
|
* @type string (JSON)
|
||
|
* @default ''
|
||
|
*/
|
||
|
params: '',
|
||
|
|
||
|
/**
|
||
|
* Returns the response object.
|
||
|
*
|
||
|
* @attribute response
|
||
|
* @type Object
|
||
|
* @default null
|
||
|
*/
|
||
|
response: null,
|
||
|
|
||
|
/**
|
||
|
* The HTTP method to use such as 'GET', 'POST', 'PUT', or 'DELETE'.
|
||
|
* Default is 'GET'.
|
||
|
*
|
||
|
* @attribute method
|
||
|
* @type string
|
||
|
* @default ''
|
||
|
*/
|
||
|
method: '',
|
||
|
|
||
|
/**
|
||
|
* HTTP request headers to send.
|
||
|
*
|
||
|
* Example:
|
||
|
*
|
||
|
* <core-ajax
|
||
|
* auto
|
||
|
* url="http://somesite.com"
|
||
|
* headers='{"X-Requested-With": "XMLHttpRequest"}'
|
||
|
* handleAs="json"
|
||
|
* on-core-response="{{handleResponse}}"></core-ajax>
|
||
|
*
|
||
|
* @attribute headers
|
||
|
* @type Object
|
||
|
* @default null
|
||
|
*/
|
||
|
headers: null,
|
||
|
|
||
|
/**
|
||
|
* Optional raw body content to send when method === "POST".
|
||
|
*
|
||
|
* Example:
|
||
|
*
|
||
|
* <core-ajax method="POST" auto url="http://somesite.com"
|
||
|
* body='{"foo":1, "bar":2}'>
|
||
|
* </core-ajax>
|
||
|
*
|
||
|
* @attribute body
|
||
|
* @type Object
|
||
|
* @default null
|
||
|
*/
|
||
|
body: null,
|
||
|
|
||
|
/**
|
||
|
* Content type to use when sending data.
|
||
|
*
|
||
|
* @attribute contentType
|
||
|
* @type string
|
||
|
* @default 'application/x-www-form-urlencoded'
|
||
|
*/
|
||
|
contentType: 'application/x-www-form-urlencoded',
|
||
|
|
||
|
/**
|
||
|
* Set the withCredentials flag on the request.
|
||
|
*
|
||
|
* @attribute withCredentials
|
||
|
* @type boolean
|
||
|
* @default false
|
||
|
*/
|
||
|
withCredentials: false,
|
||
|
|
||
|
/**
|
||
|
* Additional properties to send to core-xhr.
|
||
|
*
|
||
|
* Can be set to an object containing default properties
|
||
|
* to send as arguments to the `core-xhr.request()` method
|
||
|
* which implements the low-level communication.
|
||
|
*
|
||
|
* @property xhrArgs
|
||
|
* @type Object
|
||
|
* @default null
|
||
|
*/
|
||
|
xhrArgs: null,
|
||
|
|
||
|
ready: function() {
|
||
|
this.xhr = document.createElement('core-xhr');
|
||
|
},
|
||
|
|
||
|
receive: function(response, xhr) {
|
||
|
if (this.isSuccess(xhr)) {
|
||
|
this.processResponse(xhr);
|
||
|
} else {
|
||
|
this.error(xhr);
|
||
|
}
|
||
|
this.complete(xhr);
|
||
|
},
|
||
|
|
||
|
isSuccess: function(xhr) {
|
||
|
var status = xhr.status || 0;
|
||
|
return !status || (status >= 200 && status < 300);
|
||
|
},
|
||
|
|
||
|
processResponse: function(xhr) {
|
||
|
var response = this.evalResponse(xhr);
|
||
|
this.response = response;
|
||
|
this.fire('core-response', {response: response, xhr: xhr});
|
||
|
},
|
||
|
|
||
|
error: function(xhr) {
|
||
|
var response = xhr.status + ': ' + xhr.responseText;
|
||
|
this.fire('core-error', {response: response, xhr: xhr});
|
||
|
},
|
||
|
|
||
|
complete: function(xhr) {
|
||
|
this.fire('core-complete', {response: xhr.status, xhr: xhr});
|
||
|
},
|
||
|
|
||
|
evalResponse: function(xhr) {
|
||
|
return this[(this.handleAs || 'text') + 'Handler'](xhr);
|
||
|
},
|
||
|
|
||
|
xmlHandler: function(xhr) {
|
||
|
return xhr.responseXML;
|
||
|
},
|
||
|
|
||
|
textHandler: function(xhr) {
|
||
|
return xhr.responseText;
|
||
|
},
|
||
|
|
||
|
jsonHandler: function(xhr) {
|
||
|
var r = xhr.responseText;
|
||
|
try {
|
||
|
return JSON.parse(r);
|
||
|
} catch (x) {
|
||
|
return r;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
documentHandler: function(xhr) {
|
||
|
return xhr.response;
|
||
|
},
|
||
|
|
||
|
blobHandler: function(xhr) {
|
||
|
return xhr.response;
|
||
|
},
|
||
|
|
||
|
arraybufferHandler: function(xhr) {
|
||
|
return xhr.response;
|
||
|
},
|
||
|
|
||
|
urlChanged: function() {
|
||
|
if (!this.handleAs) {
|
||
|
var ext = String(this.url).split('.').pop();
|
||
|
switch (ext) {
|
||
|
case 'json':
|
||
|
this.handleAs = 'json';
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
this.autoGo();
|
||
|
},
|
||
|
|
||
|
paramsChanged: function() {
|
||
|
this.autoGo();
|
||
|
},
|
||
|
|
||
|
autoChanged: function() {
|
||
|
this.autoGo();
|
||
|
},
|
||
|
|
||
|
// TODO(sorvell): multiple side-effects could call autoGo
|
||
|
// during one micro-task, use a job to have only one action
|
||
|
// occur
|
||
|
autoGo: function() {
|
||
|
if (this.auto) {
|
||
|
this.goJob = this.job(this.goJob, this.go, 0);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Performs an Ajax request to the specified URL.
|
||
|
*
|
||
|
* @method go
|
||
|
*/
|
||
|
go: function() {
|
||
|
var args = this.xhrArgs || {};
|
||
|
// TODO(sjmiles): we may want XHR to default to POST if body is set
|
||
|
args.body = this.body || args.body;
|
||
|
args.params = this.params || args.params;
|
||
|
if (args.params && typeof(args.params) == 'string') {
|
||
|
args.params = JSON.parse(args.params);
|
||
|
}
|
||
|
args.headers = this.headers || args.headers || {};
|
||
|
if (args.headers && typeof(args.headers) == 'string') {
|
||
|
args.headers = JSON.parse(args.headers);
|
||
|
}
|
||
|
if (this.contentType) {
|
||
|
args.headers['content-type'] = this.contentType;
|
||
|
}
|
||
|
if (this.handleAs === 'arraybuffer' || this.handleAs === 'blob' ||
|
||
|
this.handleAs === 'document') {
|
||
|
args.responseType = this.handleAs;
|
||
|
}
|
||
|
args.withCredentials = this.withCredentials;
|
||
|
args.callback = this.receive.bind(this);
|
||
|
args.url = this.url;
|
||
|
args.method = this.method;
|
||
|
return args.url && this.xhr.request(args);
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
</script>
|
||
|
</polymer-element>
|
||
|
|
||
|
|
||
|
<!--
|
||
|
Scrapes source documentation data from input text or url.
|
||
|
|
||
|
@class context-free-parser
|
||
|
-->
|
||
|
<polymer-element name="context-free-parser" attributes="url text data" assetpath="../context-free-parser/">
|
||
|
<template>
|
||
|
|
||
|
<core-ajax url="{{url}}" response="{{text}}" auto=""></core-ajax>
|
||
|
|
||
|
</template>
|
||
|
<script>
|
||
|
|
||
|
Polymer('context-free-parser', {
|
||
|
|
||
|
text: null,
|
||
|
|
||
|
textChanged: function() {
|
||
|
if (this.text) {
|
||
|
var entities = ContextFreeParser.parse(this.text);
|
||
|
if (!entities || entities.length === 0) {
|
||
|
entities = [
|
||
|
{name: this.url.split('/').pop(), description: '**Undocumented**'}
|
||
|
];
|
||
|
}
|
||
|
this.data = { classes: entities };
|
||
|
}
|
||
|
},
|
||
|
|
||
|
dataChanged: function() {
|
||
|
this.fire('data-ready');
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
</script>
|
||
|
</polymer-element>
|
||
|
|
||
|
|
||
|
<!--
|
||
|
|
||
|
Displays formatted source documentation scraped from input urls.
|
||
|
|
||
|
@element core-doc-page
|
||
|
-->
|
||
|
|
||
|
<polymer-element name="core-doc-page" attributes="data" assetpath="../core-doc-viewer/elements/">
|
||
|
|
||
|
<!--
|
||
|
|
||
|
Set url to add documentation from that location to the view.
|
||
|
|
||
|
@attribute url
|
||
|
@type String
|
||
|
-->
|
||
|
|
||
|
<template>
|
||
|
|
||
|
<style>:host {
|
||
|
display: block;
|
||
|
position: relative;
|
||
|
}
|
||
|
|
||
|
#panel {
|
||
|
position: absolute;
|
||
|
top: 0;
|
||
|
left: 0;
|
||
|
height: 100%;
|
||
|
width: 100%;
|
||
|
}
|
||
|
|
||
|
.main {
|
||
|
padding: 0 72px;
|
||
|
max-width: 832px;
|
||
|
margin: 0 auto;
|
||
|
}
|
||
|
|
||
|
markedjs-element {
|
||
|
display: block;
|
||
|
}
|
||
|
|
||
|
h1 {
|
||
|
font-size: 52px;
|
||
|
color: #E91E63
|
||
|
}
|
||
|
|
||
|
.element {
|
||
|
font-size: 21px;
|
||
|
}
|
||
|
|
||
|
.name {
|
||
|
/* typography */
|
||
|
color: white;
|
||
|
/* font-size: 14px; */
|
||
|
font-size: 12px;
|
||
|
font-weight: bold;
|
||
|
text-decoration: none;
|
||
|
/* colors / effects */
|
||
|
background-color: #999;
|
||
|
box-shadow: 0 1px 2px 0px rgba(0, 0, 0, 0.1);
|
||
|
box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.1);
|
||
|
border-radius: 2px;
|
||
|
cursor: pointer;
|
||
|
/* metrics */
|
||
|
display: inline-block;
|
||
|
padding: 4px 12px 5px 12px;
|
||
|
margin: 4px 0;
|
||
|
}
|
||
|
|
||
|
.ntitle {
|
||
|
font-size: 26px;
|
||
|
padding-bottom: 4px;
|
||
|
border-bottom: 1px solid whitesmoke;
|
||
|
}
|
||
|
|
||
|
.box {
|
||
|
margin-bottom: 40px;
|
||
|
}
|
||
|
|
||
|
.top pre {
|
||
|
padding: 12px 13px;
|
||
|
background-color: #f8f8f8;
|
||
|
}
|
||
|
|
||
|
code {
|
||
|
font-family: Consolas, monospace;
|
||
|
border: 1px solid #ddd;
|
||
|
background-color: #f8f8f8;
|
||
|
border-radius: 3px;
|
||
|
padding: 0 3px;
|
||
|
}
|
||
|
|
||
|
pre code {
|
||
|
max-width: 832px;
|
||
|
white-space: pre-wrap;
|
||
|
overflow: hidden;
|
||
|
border: none;
|
||
|
}
|
||
|
|
||
|
/**/
|
||
|
|
||
|
.details {
|
||
|
display: flex;
|
||
|
}
|
||
|
|
||
|
.details-name {
|
||
|
flex: 1;
|
||
|
}
|
||
|
|
||
|
.details-info {
|
||
|
flex: 2;
|
||
|
}
|
||
|
|
||
|
.attribute-box {
|
||
|
}
|
||
|
|
||
|
.attribute-box .details {
|
||
|
background-color: #FFF9C4;
|
||
|
padding: 8px 16px;
|
||
|
border-bottom: 1px solid #D1CCA1;
|
||
|
}
|
||
|
|
||
|
.attribute-box .ntitle {
|
||
|
padding: 24px 16px;
|
||
|
}
|
||
|
|
||
|
.attribute-box code {
|
||
|
color: #FFAB40;
|
||
|
border: none;
|
||
|
background-color: transparent;
|
||
|
border-radius: none;
|
||
|
padding: 0;
|
||
|
font-size: 1.2em;
|
||
|
}
|
||
|
|
||
|
.property-box .ntitle {
|
||
|
padding: 24px 16px;
|
||
|
}
|
||
|
|
||
|
.property-box code {
|
||
|
color: #4285F4;
|
||
|
border: none;
|
||
|
background-color: transparent;
|
||
|
border-radius: none;
|
||
|
padding: 0;
|
||
|
font-size: 1.2em;
|
||
|
}
|
||
|
|
||
|
.property-box .details {
|
||
|
background-color: lightblue;
|
||
|
padding: 8px 16px;
|
||
|
border-bottom: 1px solid #D1CCA1;
|
||
|
}
|
||
|
|
||
|
.method-box {
|
||
|
}
|
||
|
|
||
|
.method-box .details {
|
||
|
background-color: #F0F4C3;
|
||
|
padding: 8px 16px;
|
||
|
border-bottom: 1px solid #D1CCA1;
|
||
|
}
|
||
|
|
||
|
.method-box .ntitle {
|
||
|
background-color: #9E9D24;
|
||
|
padding: 24px 16px;
|
||
|
}
|
||
|
|
||
|
.method-box code {
|
||
|
color: #9E9D24;
|
||
|
border: none;
|
||
|
background-color: transparent;
|
||
|
border-radius: none;
|
||
|
padding: 0;
|
||
|
font-size: 1.2em;
|
||
|
}
|
||
|
|
||
|
.event-box {
|
||
|
}
|
||
|
|
||
|
.event-box .details {
|
||
|
background-color: #B2DFDB;
|
||
|
padding: 8px 16px;
|
||
|
border-bottom: 1px solid #92B7B3;
|
||
|
}
|
||
|
|
||
|
.event-box .ntitle {
|
||
|
background-color: #009688;
|
||
|
padding: 24px 16px;
|
||
|
}
|
||
|
|
||
|
.event-box code {
|
||
|
color: #009688;
|
||
|
border: none;
|
||
|
background-color: transparent;
|
||
|
border-radius: none;
|
||
|
padding: 0;
|
||
|
font-size: 1.2em;
|
||
|
}
|
||
|
|
||
|
code, pre {
|
||
|
color: #9f499b;
|
||
|
font-family: "Source Code Pro",Monaco,Menlo,Consolas,"Courier New",monospace;
|
||
|
}
|
||
|
|
||
|
pre .typ,pre .inline,.prettyprint .typ,.prettyprint .inline {
|
||
|
color: #6b499f
|
||
|
}
|
||
|
pre .pun,.prettyprint .pun {
|
||
|
color: #5c6bc0
|
||
|
}
|
||
|
pre .str,pre .string,.prettyprint .str,.prettyprint .string {
|
||
|
color: #ff4081
|
||
|
}
|
||
|
pre .pln,.prettyprint .pln {
|
||
|
color: #7986cb
|
||
|
}
|
||
|
pre .kwd,.prettyprint .kwd {
|
||
|
color: #d61a7f
|
||
|
}
|
||
|
pre .atn,pre .attribute-name,.prettyprint .atn,.prettyprint .attribute-name {
|
||
|
color: #6b499f
|
||
|
}
|
||
|
pre .atv,pre .attribute-value,.prettyprint .atv,.prettyprint .attribute-value {
|
||
|
color: #7986cb
|
||
|
}
|
||
|
pre .com,pre .comment,.prettyprint .com,.prettyprint .comment {
|
||
|
color: #8a8a8a
|
||
|
}</style>
|
||
|
|
||
|
<core-header-panel id="panel" mode="waterfall">
|
||
|
|
||
|
<!--<core-toolbar>
|
||
|
<span style="margin: 0 72px;">{{data.name}}</span>
|
||
|
</core-toolbar>-->
|
||
|
|
||
|
<div class="main" on-marked-js-highlight="{{hilight}}">
|
||
|
|
||
|
<h1 style="font-size: 52px; color: #E91E63;">
|
||
|
{{data.name}}
|
||
|
</h1>
|
||
|
|
||
|
<p>
|
||
|
<core-icon icon="home"></core-icon> <a href="{{data | homepageFilter}}">Home Page</a>
|
||
|
</p>
|
||
|
|
||
|
<template if="{{data.extends}}">
|
||
|
<section class="box">
|
||
|
<div class="ntitle">Extends</div>
|
||
|
<p><a href="#{{data.extends}}">{{data.extends}}</a></p>
|
||
|
</section>
|
||
|
</template>
|
||
|
|
||
|
<template if="{{data.description}}">
|
||
|
<section class="box top">
|
||
|
<div class="ntitle">Summary</div>
|
||
|
<marked-element text="{{data.description}}"></marked-element>
|
||
|
</section>
|
||
|
</template>
|
||
|
|
||
|
<template if="{{data.attributes.length}}">
|
||
|
<section class="box attribute-box">
|
||
|
<div class="ntitle" style="background-color: #FFAB40; color: white;">Attributes</div>
|
||
|
<template repeat="{{data.attributes}}">
|
||
|
<div class="details">
|
||
|
<div class="details-name">
|
||
|
<p><code>{{name}}</code></p>
|
||
|
</div>
|
||
|
<div class="details-info">
|
||
|
<p><code>{{type}}</code></p>
|
||
|
<marked-element text="{{description}}"></marked-element>
|
||
|
</div>
|
||
|
</div>
|
||
|
</template>
|
||
|
</section>
|
||
|
</template>
|
||
|
|
||
|
<template if="{{data.properties.length}}">
|
||
|
<section class="box property-box">
|
||
|
<div class="ntitle" style="background-color: #4285F4; color: white;">Properties</div>
|
||
|
<template repeat="{{data.properties}}">
|
||
|
<div class="details">
|
||
|
<div class="details-name">
|
||
|
<p><code>{{name}}</code></p>
|
||
|
</div>
|
||
|
<div class="details-info">
|
||
|
<p><code>{{type}}</code></p>
|
||
|
<marked-element text="{{description}}"></marked-element>
|
||
|
</div>
|
||
|
</div>
|
||
|
</template>
|
||
|
</section>
|
||
|
</template>
|
||
|
|
||
|
<template if="{{data.events.length}}">
|
||
|
<section class="box event-box">
|
||
|
<div class="ntitle" style="color: white;">Events</div>
|
||
|
<template repeat="{{data.events}}">
|
||
|
<div class="details">
|
||
|
<div class="details-name">
|
||
|
<p><code>{{name}}</code></p>
|
||
|
</div>
|
||
|
<div class="details-info">
|
||
|
<marked-element text="{{description}}"></marked-element>
|
||
|
</div>
|
||
|
</div>
|
||
|
</template>
|
||
|
</section>
|
||
|
</template>
|
||
|
|
||
|
<template if="{{data.methods.length}}">
|
||
|
<section class="box method-box">
|
||
|
<div class="ntitle" style="color: white;">Methods</div>
|
||
|
<template repeat="{{data.methods}}">
|
||
|
<div class="details">
|
||
|
<div class="details-name">
|
||
|
<p><code>{{name}}</code></p>
|
||
|
</div>
|
||
|
<div class="details-info">
|
||
|
<marked-element text="{{description}}"></marked-element>
|
||
|
</div>
|
||
|
</div>
|
||
|
</template>
|
||
|
</section>
|
||
|
</template>
|
||
|
|
||
|
</div>
|
||
|
|
||
|
</core-header-panel>
|
||
|
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
|
||
|
Polymer('core-doc-page', {
|
||
|
|
||
|
hilight: function(event, detail, sender) {
|
||
|
detail.code = prettyPrintOne((detail.code || '').replace(/</g,'<').replace(/>/g,'>'));
|
||
|
},
|
||
|
|
||
|
homepageFilter: function(data) {
|
||
|
if (!data) {
|
||
|
return '';
|
||
|
}
|
||
|
if (!data.homepage || data.homepage === 'github.io') {
|
||
|
return '//polymer.github.io/' + data.name;
|
||
|
} else {
|
||
|
return data.homepage;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
</script>
|
||
|
|
||
|
</polymer-element>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<!--
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
-->
|
||
|
|
||
|
<!--
|
||
|
`core-menu` is a selector which styles to looks like a menu.
|
||
|
|
||
|
<core-menu selected="0">
|
||
|
<core-item icon="settings" label="Settings"></core-item>
|
||
|
<core-item icon="dialog" label="Dialog"></core-item>
|
||
|
<core-item icon="search" label="Search"></core-item>
|
||
|
</core-menu>
|
||
|
|
||
|
When an item is selected the `core-selected` class is added to it. The user can
|
||
|
use the class to add more stylings to the selected item.
|
||
|
|
||
|
core-item.core-selected {
|
||
|
color: red;
|
||
|
}
|
||
|
|
||
|
The `selectedItem` property references the selected item.
|
||
|
|
||
|
<core-menu selected="0" selectedItem="{{item}}">
|
||
|
<core-item icon="settings" label="Settings"></core-item>
|
||
|
<core-item icon="dialog" label="Dialog"></core-item>
|
||
|
<core-item icon="search" label="Search"></core-item>
|
||
|
</core-menu>
|
||
|
|
||
|
<div>selected label: {{item.label}}</div>
|
||
|
|
||
|
The `core-select` event signals selection change.
|
||
|
|
||
|
<core-menu selected="0" on-core-select="{{selectAction}}">
|
||
|
<core-item icon="settings" label="Settings"></core-item>
|
||
|
<core-item icon="dialog" label="Dialog"></core-item>
|
||
|
<core-item icon="search" label="Search"></core-item>
|
||
|
</core-menu>
|
||
|
|
||
|
...
|
||
|
|
||
|
selectAction: function(e, detail) {
|
||
|
if (detail.isSelected) {
|
||
|
var selectedItem = detail.item;
|
||
|
...
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@group Polymer Core Elements
|
||
|
@element core-menu
|
||
|
@extends core-selector
|
||
|
-->
|
||
|
|
||
|
<!--
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
-->
|
||
|
|
||
|
<!--
|
||
|
@group Polymer Core Elements
|
||
|
|
||
|
`<core-selector>` is used to manage a list of elements that can be selected.
|
||
|
|
||
|
The attribute `selected` indicates which item element is being selected.
|
||
|
The attribute `multi` indicates if multiple items can be selected at once.
|
||
|
Tapping on the item element would fire `core-activate` event. Use
|
||
|
`core-select` event to listen for selection changes.
|
||
|
|
||
|
Example:
|
||
|
|
||
|
<core-selector selected="0">
|
||
|
<div>Item 1</div>
|
||
|
<div>Item 2</div>
|
||
|
<div>Item 3</div>
|
||
|
</core-selector>
|
||
|
|
||
|
`<core-selector>` is not styled. Use the `core-selected` CSS class to style the selected element.
|
||
|
|
||
|
<style>
|
||
|
.item.core-selected {
|
||
|
background: #eee;
|
||
|
}
|
||
|
</style>
|
||
|
...
|
||
|
<core-selector>
|
||
|
<div class="item">Item 1</div>
|
||
|
<div class="item">Item 2</div>
|
||
|
<div class="item">Item 3</div>
|
||
|
</core-selector>
|
||
|
|
||
|
@element core-selector
|
||
|
@status stable
|
||
|
@homepage github.io
|
||
|
-->
|
||
|
|
||
|
<!--
|
||
|
Fired when an item's selection state is changed. This event is fired both
|
||
|
when an item is selected or deselected. The `isSelected` detail property
|
||
|
contains the selection state.
|
||
|
|
||
|
@event core-select
|
||
|
@param {Object} detail
|
||
|
@param {boolean} detail.isSelected true for selection and false for deselection
|
||
|
@param {Object} detail.item the item element
|
||
|
-->
|
||
|
<!--
|
||
|
Fired when an item element is tapped.
|
||
|
|
||
|
@event core-activate
|
||
|
@param {Object} detail
|
||
|
@param {Object} detail.item the item element
|
||
|
-->
|
||
|
|
||
|
|
||
|
<!--
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
-->
|
||
|
<!--
|
||
|
@group Polymer Core Elements
|
||
|
|
||
|
The `<core-selection>` element is used to manage selection state. It has no
|
||
|
visual appearance and is typically used in conjunction with another element.
|
||
|
For example, [core-selector](#core-selector)
|
||
|
use a `<core-selection>` to manage selection.
|
||
|
|
||
|
To mark an item as selected, call the `select(item)` method on
|
||
|
`<core-selection>`. The item itself is an argument to this method.
|
||
|
|
||
|
The `<core-selection>`element manages selection state for any given set of
|
||
|
items. When an item is selected, the `core-select` event is fired.
|
||
|
|
||
|
The attribute `multi` indicates if multiple items can be selected at once.
|
||
|
|
||
|
Example:
|
||
|
|
||
|
<polymer-element name="selection-example">
|
||
|
<template>
|
||
|
<style>
|
||
|
polyfill-next-selector { content: ':host > .selected'; }
|
||
|
::content > .selected {
|
||
|
font-weight: bold;
|
||
|
font-style: italic;
|
||
|
}
|
||
|
</style>
|
||
|
<ul on-tap="{{itemTapAction}}">
|
||
|
<content></content>
|
||
|
</ul>
|
||
|
<core-selection id="selection" multi
|
||
|
on-core-select="{{selectAction}}"></core-selection>
|
||
|
</template>
|
||
|
<script>
|
||
|
Polymer('selection-example', {
|
||
|
itemTapAction: function(e, detail, sender) {
|
||
|
this.$.selection.select(e.target);
|
||
|
},
|
||
|
selectAction: function(e, detail, sender) {
|
||
|
detail.item.classList.toggle('selected', detail.isSelected);
|
||
|
}
|
||
|
});
|
||
|
</script>
|
||
|
</polymer-element>
|
||
|
|
||
|
<selection-example>
|
||
|
<li>Red</li>
|
||
|
<li>Green</li>
|
||
|
<li>Blue</li>
|
||
|
</selection-example>
|
||
|
|
||
|
@element core-selection
|
||
|
-->
|
||
|
|
||
|
<!--
|
||
|
Fired when an item's selection state is changed. This event is fired both
|
||
|
when an item is selected or deselected. The `isSelected` detail property
|
||
|
contains the selection state.
|
||
|
|
||
|
@event core-select
|
||
|
@param {Object} detail
|
||
|
@param {boolean} detail.isSelected true for selection and false for de-selection
|
||
|
@param {Object} detail.item the item element
|
||
|
-->
|
||
|
|
||
|
|
||
|
<polymer-element name="core-selection" attributes="multi" hidden assetpath="../core-selection/">
|
||
|
<script>
|
||
|
Polymer('core-selection', {
|
||
|
/**
|
||
|
* If true, multiple selections are allowed.
|
||
|
*
|
||
|
* @attribute multi
|
||
|
* @type boolean
|
||
|
* @default false
|
||
|
*/
|
||
|
multi: false,
|
||
|
ready: function() {
|
||
|
this.clear();
|
||
|
},
|
||
|
clear: function() {
|
||
|
this.selection = [];
|
||
|
},
|
||
|
/**
|
||
|
* Retrieves the selected item(s).
|
||
|
* @method getSelection
|
||
|
* @returns Returns the selected item(s). If the multi property is true,
|
||
|
* getSelection will return an array, otherwise it will return
|
||
|
* the selected item or undefined if there is no selection.
|
||
|
*/
|
||
|
getSelection: function() {
|
||
|
return this.multi ? this.selection : this.selection[0];
|
||
|
},
|
||
|
/**
|
||
|
* Indicates if a given item is selected.
|
||
|
* @method isSelected
|
||
|
* @param {any} item The item whose selection state should be checked.
|
||
|
* @returns Returns true if `item` is selected.
|
||
|
*/
|
||
|
isSelected: function(item) {
|
||
|
return this.selection.indexOf(item) >= 0;
|
||
|
},
|
||
|
setItemSelected: function(item, isSelected) {
|
||
|
if (item !== undefined && item !== null) {
|
||
|
if (isSelected) {
|
||
|
this.selection.push(item);
|
||
|
} else {
|
||
|
var i = this.selection.indexOf(item);
|
||
|
if (i >= 0) {
|
||
|
this.selection.splice(i, 1);
|
||
|
}
|
||
|
}
|
||
|
this.fire("core-select", {isSelected: isSelected, item: item});
|
||
|
}
|
||
|
},
|
||
|
/**
|
||
|
* Set the selection state for a given `item`. If the multi property
|
||
|
* is true, then the selected state of `item` will be toggled; otherwise
|
||
|
* the `item` will be selected.
|
||
|
* @method select
|
||
|
* @param {any} item: The item to select.
|
||
|
*/
|
||
|
select: function(item) {
|
||
|
if (this.multi) {
|
||
|
this.toggle(item);
|
||
|
} else if (this.getSelection() !== item) {
|
||
|
this.setItemSelected(this.getSelection(), false);
|
||
|
this.setItemSelected(item, true);
|
||
|
}
|
||
|
},
|
||
|
/**
|
||
|
* Toggles the selection state for `item`.
|
||
|
* @method toggle
|
||
|
* @param {any} item: The item to toggle.
|
||
|
*/
|
||
|
toggle: function(item) {
|
||
|
this.setItemSelected(item, !this.isSelected(item));
|
||
|
}
|
||
|
});
|
||
|
</script>
|
||
|
</polymer-element>
|
||
|
|
||
|
|
||
|
<polymer-element name="core-selector" attributes="selected multi valueattr selectedClass selectedProperty selectedAttribute selectedItem selectedModel selectedIndex notap target itemsSelector activateEvent" assetpath="../core-selector/">
|
||
|
|
||
|
<template>
|
||
|
<core-selection id="selection" multi="{{multi}}" on-core-select="{{selectionSelect}}"></core-selection>
|
||
|
<content id="items" select="*"></content>
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
|
||
|
Polymer('core-selector', {
|
||
|
|
||
|
/**
|
||
|
* Gets or sets the selected element. Default to use the index
|
||
|
* of the item element.
|
||
|
*
|
||
|
* If you want a specific attribute value of the element to be
|
||
|
* used instead of index, set "valueattr" to that attribute name.
|
||
|
*
|
||
|
* Example:
|
||
|
*
|
||
|
* <core-selector valueattr="label" selected="foo">
|
||
|
* <div label="foo"></div>
|
||
|
* <div label="bar"></div>
|
||
|
* <div label="zot"></div>
|
||
|
* </core-selector>
|
||
|
*
|
||
|
* In multi-selection this should be an array of values.
|
||
|
*
|
||
|
* Example:
|
||
|
*
|
||
|
* <core-selector id="selector" valueattr="label" multi>
|
||
|
* <div label="foo"></div>
|
||
|
* <div label="bar"></div>
|
||
|
* <div label="zot"></div>
|
||
|
* </core-selector>
|
||
|
*
|
||
|
* this.$.selector.selected = ['foo', 'zot'];
|
||
|
*
|
||
|
* @attribute selected
|
||
|
* @type Object
|
||
|
* @default null
|
||
|
*/
|
||
|
selected: null,
|
||
|
|
||
|
/**
|
||
|
* If true, multiple selections are allowed.
|
||
|
*
|
||
|
* @attribute multi
|
||
|
* @type boolean
|
||
|
* @default false
|
||
|
*/
|
||
|
multi: false,
|
||
|
|
||
|
/**
|
||
|
* Specifies the attribute to be used for "selected" attribute.
|
||
|
*
|
||
|
* @attribute valueattr
|
||
|
* @type string
|
||
|
* @default 'name'
|
||
|
*/
|
||
|
valueattr: 'name',
|
||
|
|
||
|
/**
|
||
|
* Specifies the CSS class to be used to add to the selected element.
|
||
|
*
|
||
|
* @attribute selectedClass
|
||
|
* @type string
|
||
|
* @default 'core-selected'
|
||
|
*/
|
||
|
selectedClass: 'core-selected',
|
||
|
|
||
|
/**
|
||
|
* Specifies the property to be used to set on the selected element
|
||
|
* to indicate its active state.
|
||
|
*
|
||
|
* @attribute selectedProperty
|
||
|
* @type string
|
||
|
* @default ''
|
||
|
*/
|
||
|
selectedProperty: '',
|
||
|
|
||
|
/**
|
||
|
* Specifies the attribute to set on the selected element to indicate
|
||
|
* its active state.
|
||
|
*
|
||
|
* @attribute selectedAttribute
|
||
|
* @type string
|
||
|
* @default 'active'
|
||
|
*/
|
||
|
selectedAttribute: 'active',
|
||
|
|
||
|
/**
|
||
|
* Returns the currently selected element. In multi-selection this returns
|
||
|
* an array of selected elements.
|
||
|
*
|
||
|
* @attribute selectedItem
|
||
|
* @type Object
|
||
|
* @default null
|
||
|
*/
|
||
|
selectedItem: null,
|
||
|
|
||
|
/**
|
||
|
* In single selection, this returns the model associated with the
|
||
|
* selected element.
|
||
|
*
|
||
|
* @attribute selectedModel
|
||
|
* @type Object
|
||
|
* @default null
|
||
|
*/
|
||
|
selectedModel: null,
|
||
|
|
||
|
/**
|
||
|
* In single selection, this returns the selected index.
|
||
|
*
|
||
|
* @attribute selectedIndex
|
||
|
* @type number
|
||
|
* @default -1
|
||
|
*/
|
||
|
selectedIndex: -1,
|
||
|
|
||
|
/**
|
||
|
* The target element that contains items. If this is not set
|
||
|
* core-selector is the container.
|
||
|
*
|
||
|
* @attribute target
|
||
|
* @type Object
|
||
|
* @default null
|
||
|
*/
|
||
|
target: null,
|
||
|
|
||
|
/**
|
||
|
* This can be used to query nodes from the target node to be used for
|
||
|
* selection items. Note this only works if the 'target' property is set.
|
||
|
*
|
||
|
* Example:
|
||
|
*
|
||
|
* <core-selector target="{{$.myForm}}" itemsSelector="input[type=radio]"></core-selector>
|
||
|
* <form id="myForm">
|
||
|
* <label><input type="radio" name="color" value="red"> Red</label> <br>
|
||
|
* <label><input type="radio" name="color" value="green"> Green</label> <br>
|
||
|
* <label><input type="radio" name="color" value="blue"> Blue</label> <br>
|
||
|
* <p>color = {{color}}</p>
|
||
|
* </form>
|
||
|
*
|
||
|
* @attribute itemSelector
|
||
|
* @type string
|
||
|
* @default ''
|
||
|
*/
|
||
|
itemsSelector: '',
|
||
|
|
||
|
/**
|
||
|
* The event that would be fired from the item element to indicate
|
||
|
* it is being selected.
|
||
|
*
|
||
|
* @attribute activateEvent
|
||
|
* @type string
|
||
|
* @default 'tap'
|
||
|
*/
|
||
|
activateEvent: 'tap',
|
||
|
|
||
|
/**
|
||
|
* Set this to true to disallow changing the selection via the
|
||
|
* `activateEvent`.
|
||
|
*
|
||
|
* @attribute notap
|
||
|
* @type boolean
|
||
|
* @default false
|
||
|
*/
|
||
|
notap: false,
|
||
|
|
||
|
ready: function() {
|
||
|
this.activateListener = this.activateHandler.bind(this);
|
||
|
this.observer = new MutationObserver(this.updateSelected.bind(this));
|
||
|
if (!this.target) {
|
||
|
this.target = this;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
get items() {
|
||
|
if (!this.target) {
|
||
|
return [];
|
||
|
}
|
||
|
var nodes = this.target !== this ? (this.itemsSelector ?
|
||
|
this.target.querySelectorAll(this.itemsSelector) :
|
||
|
this.target.children) : this.$.items.getDistributedNodes();
|
||
|
return Array.prototype.filter.call(nodes || [], function(n) {
|
||
|
return n && n.localName !== 'template';
|
||
|
});
|
||
|
},
|
||
|
|
||
|
targetChanged: function(old) {
|
||
|
if (old) {
|
||
|
this.removeListener(old);
|
||
|
this.observer.disconnect();
|
||
|
this.clearSelection();
|
||
|
}
|
||
|
if (this.target) {
|
||
|
this.addListener(this.target);
|
||
|
this.observer.observe(this.target, {childList: true});
|
||
|
this.updateSelected();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
addListener: function(node) {
|
||
|
node.addEventListener(this.activateEvent, this.activateListener);
|
||
|
},
|
||
|
|
||
|
removeListener: function(node) {
|
||
|
node.removeEventListener(this.activateEvent, this.activateListener);
|
||
|
},
|
||
|
|
||
|
get selection() {
|
||
|
return this.$.selection.getSelection();
|
||
|
},
|
||
|
|
||
|
selectedChanged: function() {
|
||
|
this.updateSelected();
|
||
|
},
|
||
|
|
||
|
updateSelected: function() {
|
||
|
this.validateSelected();
|
||
|
if (this.multi) {
|
||
|
this.clearSelection();
|
||
|
this.selected && this.selected.forEach(function(s) {
|
||
|
this.valueToSelection(s);
|
||
|
}, this);
|
||
|
} else {
|
||
|
this.valueToSelection(this.selected);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
validateSelected: function() {
|
||
|
// convert to an array for multi-selection
|
||
|
if (this.multi && !Array.isArray(this.selected) &&
|
||
|
this.selected !== null && this.selected !== undefined) {
|
||
|
this.selected = [this.selected];
|
||
|
}
|
||
|
},
|
||
|
|
||
|
clearSelection: function() {
|
||
|
if (this.multi) {
|
||
|
this.selection.slice().forEach(function(s) {
|
||
|
this.$.selection.setItemSelected(s, false);
|
||
|
}, this);
|
||
|
} else {
|
||
|
this.$.selection.setItemSelected(this.selection, false);
|
||
|
}
|
||
|
this.selectedItem = null;
|
||
|
this.$.selection.clear();
|
||
|
},
|
||
|
|
||
|
valueToSelection: function(value) {
|
||
|
var item = (value === null || value === undefined) ?
|
||
|
null : this.items[this.valueToIndex(value)];
|
||
|
this.$.selection.select(item);
|
||
|
},
|
||
|
|
||
|
updateSelectedItem: function() {
|
||
|
this.selectedItem = this.selection;
|
||
|
},
|
||
|
|
||
|
selectedItemChanged: function() {
|
||
|
if (this.selectedItem) {
|
||
|
var t = this.selectedItem.templateInstance;
|
||
|
this.selectedModel = t ? t.model : undefined;
|
||
|
} else {
|
||
|
this.selectedModel = null;
|
||
|
}
|
||
|
this.selectedIndex = this.selectedItem ?
|
||
|
parseInt(this.valueToIndex(this.selected)) : -1;
|
||
|
},
|
||
|
|
||
|
valueToIndex: function(value) {
|
||
|
// find an item with value == value and return it's index
|
||
|
for (var i=0, items=this.items, c; (c=items[i]); i++) {
|
||
|
if (this.valueForNode(c) == value) {
|
||
|
return i;
|
||
|
}
|
||
|
}
|
||
|
// if no item found, the value itself is probably the index
|
||
|
return value;
|
||
|
},
|
||
|
|
||
|
valueForNode: function(node) {
|
||
|
return node[this.valueattr] || node.getAttribute(this.valueattr);
|
||
|
},
|
||
|
|
||
|
// events fired from <core-selection> object
|
||
|
selectionSelect: function(e, detail) {
|
||
|
this.updateSelectedItem();
|
||
|
if (detail.item) {
|
||
|
this.applySelection(detail.item, detail.isSelected);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
applySelection: function(item, isSelected) {
|
||
|
if (this.selectedClass) {
|
||
|
item.classList.toggle(this.selectedClass, isSelected);
|
||
|
}
|
||
|
if (this.selectedProperty) {
|
||
|
item[this.selectedProperty] = isSelected;
|
||
|
}
|
||
|
if (this.selectedAttribute && item.setAttribute) {
|
||
|
if (isSelected) {
|
||
|
item.setAttribute(this.selectedAttribute, '');
|
||
|
} else {
|
||
|
item.removeAttribute(this.selectedAttribute);
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
// event fired from host
|
||
|
activateHandler: function(e) {
|
||
|
if (!this.notap) {
|
||
|
var i = this.findDistributedTarget(e.target, this.items);
|
||
|
if (i >= 0) {
|
||
|
var item = this.items[i];
|
||
|
var s = this.valueForNode(item) || i;
|
||
|
if (this.multi) {
|
||
|
if (this.selected) {
|
||
|
this.addRemoveSelected(s);
|
||
|
} else {
|
||
|
this.selected = [s];
|
||
|
}
|
||
|
} else {
|
||
|
this.selected = s;
|
||
|
}
|
||
|
this.asyncFire('core-activate', {item: item});
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
addRemoveSelected: function(value) {
|
||
|
var i = this.selected.indexOf(value);
|
||
|
if (i >= 0) {
|
||
|
this.selected.splice(i, 1);
|
||
|
} else {
|
||
|
this.selected.push(value);
|
||
|
}
|
||
|
this.valueToSelection(value);
|
||
|
},
|
||
|
|
||
|
findDistributedTarget: function(target, nodes) {
|
||
|
// find first ancestor of target (including itself) that
|
||
|
// is in nodes, if any
|
||
|
while (target && target != this) {
|
||
|
var i = Array.prototype.indexOf.call(nodes, target);
|
||
|
if (i >= 0) {
|
||
|
return i;
|
||
|
}
|
||
|
target = target.parentNode;
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
</script>
|
||
|
</polymer-element>
|
||
|
|
||
|
|
||
|
<style shim-shadowdom="">/*
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
*/
|
||
|
|
||
|
html /deep/ core-menu {
|
||
|
display: block;
|
||
|
margin: 12px;
|
||
|
}
|
||
|
|
||
|
polyfill-next-selector { content: 'core-menu > core-item'; }
|
||
|
html /deep/ core-menu::shadow ::content > core-item {
|
||
|
cursor: default;
|
||
|
}
|
||
|
</style>
|
||
|
|
||
|
<polymer-element name="core-menu" extends="core-selector" assetpath="../core-menu/">
|
||
|
<script>
|
||
|
Polymer('core-menu',{});
|
||
|
</script>
|
||
|
</polymer-element>
|
||
|
|
||
|
<!--
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
-->
|
||
|
|
||
|
<!--
|
||
|
`core-item` is a simple line-item object: a label and/or an icon that can also
|
||
|
act as a link.
|
||
|
|
||
|
Example:
|
||
|
|
||
|
<core-item icon="settings" label="Settings"></core-item>
|
||
|
|
||
|
To use as a link, put <a> element in the item.
|
||
|
|
||
|
Example:
|
||
|
|
||
|
<core-item icon="settings" label="Settings">
|
||
|
<a href="#settings" target="_self"></a>
|
||
|
</core-item>
|
||
|
|
||
|
@group Polymer Core Elements
|
||
|
@element core-item
|
||
|
@homepage github.io
|
||
|
-->
|
||
|
|
||
|
|
||
|
|
||
|
<style shim-shadowdom="">/*
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
*/
|
||
|
|
||
|
html /deep/ core-item {
|
||
|
display: block;
|
||
|
position: relative;
|
||
|
min-height: 40px;
|
||
|
white-space: nowrap;
|
||
|
}
|
||
|
|
||
|
html /deep/ core-item.core-selected {
|
||
|
font-weight: bold;
|
||
|
}
|
||
|
|
||
|
html /deep/ core-item::shadow core-icon {
|
||
|
margin: 0 16px 0 4px;
|
||
|
}
|
||
|
|
||
|
html /deep/ core-item::shadow ::content > a {
|
||
|
position: absolute;
|
||
|
top: 0;
|
||
|
right: 0;
|
||
|
bottom: 0;
|
||
|
left: 0;
|
||
|
}
|
||
|
</style>
|
||
|
|
||
|
<polymer-element name="core-item" attributes="label icon src" horizontal="" center="" layout="" assetpath="../core-item/">
|
||
|
<template>
|
||
|
|
||
|
<core-icon src="{{src}}" icon="{{icon}}" hidden?="{{!src && !icon}}"></core-icon>{{label}}<content></content>
|
||
|
|
||
|
</template>
|
||
|
<script>
|
||
|
|
||
|
Polymer('core-item', {
|
||
|
|
||
|
/**
|
||
|
* The URL of an image for the icon.
|
||
|
*
|
||
|
* @attribute src
|
||
|
* @type string
|
||
|
* @default ''
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* Specifies the icon from the Polymer icon set.
|
||
|
*
|
||
|
* @attribute icon
|
||
|
* @type string
|
||
|
* @default ''
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* Specifies the label for the menu item.
|
||
|
*
|
||
|
* @attribute label
|
||
|
* @type string
|
||
|
* @default ''
|
||
|
*/
|
||
|
|
||
|
});
|
||
|
|
||
|
</script>
|
||
|
</polymer-element>
|
||
|
|
||
|
|
||
|
<!--
|
||
|
@class core-doc-toc
|
||
|
-->
|
||
|
|
||
|
<polymer-element name="core-doc-toc" attributes="data selected" assetpath="../core-doc-viewer/elements/">
|
||
|
|
||
|
<template>
|
||
|
|
||
|
<style>:host {
|
||
|
display: block;
|
||
|
position: relative;
|
||
|
border-right: 1px solid silver;
|
||
|
}
|
||
|
|
||
|
core-header-panel {
|
||
|
position: absolute;
|
||
|
top: 0;
|
||
|
left: 0;
|
||
|
height: 100%;
|
||
|
width: 100%;
|
||
|
}
|
||
|
|
||
|
core-toolbar {
|
||
|
background-color: #eeeeee;
|
||
|
}
|
||
|
</style>
|
||
|
|
||
|
<core-header-panel mode="waterfall">
|
||
|
|
||
|
<!-- <core-toolbar theme="core-light-theme">
|
||
|
<core-icon-button icon="menu"></core-icon-button>
|
||
|
<span core-flex>Topics</span>
|
||
|
<core-icon-button icon="search" on-tap="{{searchAction}}"></core-icon-button>
|
||
|
</core-toolbar>
|
||
|
|
||
|
<core-toolbar id="searchBar" style="background-color: #C2185B; position: absolute; top: 0; left: 0; right: 0; opacity: 0; display: none;" class="seamed" theme="core-dark-theme">
|
||
|
<core-icon-button icon="search"></core-icon-button>
|
||
|
<core-icon-button icon="close" on-tap="{{closeSearchAction}}"></core-icon-button>
|
||
|
</core-toolbar>-->
|
||
|
|
||
|
<core-menu selected="{{selected}}">
|
||
|
<template repeat="{{data}}">
|
||
|
<core-item><a href="#{{name}}">{{name}}</a></core-item>
|
||
|
</template>
|
||
|
</core-menu>
|
||
|
|
||
|
</core-header-panel>
|
||
|
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
|
||
|
Polymer('core-doc-toc', {
|
||
|
|
||
|
searchAction: function() {
|
||
|
this.$.searchBar.style.opacity = 1;
|
||
|
this.$.searchBar.style.display = '';
|
||
|
},
|
||
|
|
||
|
closeSearchAction: function() {
|
||
|
this.$.searchBar.style.opacity = 0;
|
||
|
this.$.searchBar.style.display = 'none';
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
</script>
|
||
|
|
||
|
</polymer-element>
|
||
|
|
||
|
|
||
|
|
||
|
<!--
|
||
|
Displays formatted source documentation scraped from input urls.
|
||
|
|
||
|
Documentation can be encoded into html comments (<!-- ... -->) or using JsDoc notation (/** ... */).
|
||
|
|
||
|
When using JsDoc notation, remember that the left-margin includes an asterisk and a single space.
|
||
|
This is important for markdown constructs that count spaces. Code blocks for example, must be
|
||
|
five spaces from the first asterisk.
|
||
|
|
||
|
## Markdown
|
||
|
|
||
|
Markdown format is supported.
|
||
|
|
||
|
### Links
|
||
|
|
||
|
Arbitrary links can be encoded using [standard markdown format](http://daringfireball.net/projects/markdown/syntax).
|
||
|
[GitHub Flavored Markdown](https://help.github.com/articles/github-flavored-markdown) is also supported.
|
||
|
|
||
|
Links to other topics can be made with hash-links [core-doc-viewer](#core-doc-viewer).
|
||
|
|
||
|
### Code
|
||
|
|
||
|
Example
|
||
|
|
||
|
Four space indents indicate code blocks.
|
||
|
|
||
|
<code>blocks are syntax highlighted</code>
|
||
|
|
||
|
<script>
|
||
|
while(true) {
|
||
|
javascript('is highlighted also');
|
||
|
}
|
||
|
</script>
|
||
|
|
||
|
### Blockquote
|
||
|
|
||
|
> Blockquote is supported for long text that needs to wrap with a common left side indent.
|
||
|
> Blockquote is supported for long text that needs to wrap with a common left side indent.
|
||
|
|
||
|
### Lists
|
||
|
|
||
|
1. enumerated
|
||
|
1. lists
|
||
|
|
||
|
Use - or + for bullet points:
|
||
|
|
||
|
- bullet
|
||
|
- lists
|
||
|
|
||
|
### Tables
|
||
|
|
||
|
| First Header | Second Header |
|
||
|
| ------------- | ------------- |
|
||
|
| Content Cell | Content Cell |
|
||
|
| Content Cell | Content Cell |
|
||
|
|
||
|
### HTML
|
||
|
|
||
|
Arbitrary HTML is also supported
|
||
|
|
||
|
<input><button>Button</button><hr/>
|
||
|
|
||
|
@class core-doc-viewer
|
||
|
@homepage github.io
|
||
|
-->
|
||
|
|
||
|
<polymer-element name="core-doc-viewer" attributes="sources route url" assetpath="../core-doc-viewer/">
|
||
|
|
||
|
<template>
|
||
|
|
||
|
<style>
|
||
|
|
||
|
core-doc-toc {
|
||
|
display: none;
|
||
|
width: 332px;
|
||
|
overflow-x: hidden;
|
||
|
}
|
||
|
|
||
|
</style>
|
||
|
|
||
|
<context-free-parser url="{{url}}" on-data-ready="{{parserDataReady}}"></context-free-parser>
|
||
|
|
||
|
<template repeat="{{sources}}">
|
||
|
<context-free-parser url="{{}}" on-data-ready="{{parserDataReady}}"></context-free-parser>
|
||
|
</template>
|
||
|
|
||
|
<core-layout></core-layout>
|
||
|
<core-doc-toc id="toc" data="{{classes}}" selected="{{selected}}"></core-doc-toc>
|
||
|
<core-doc-page core-flex="" data="{{data}}"></core-doc-page>
|
||
|
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
|
||
|
Polymer('core-doc-viewer', {
|
||
|
/**
|
||
|
* A single file to parse for docs
|
||
|
*
|
||
|
* @attribute url
|
||
|
* @type String
|
||
|
* @default ''
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* Class documentation extracted from the parser
|
||
|
*
|
||
|
* @property classes
|
||
|
* @type Array
|
||
|
* @default []
|
||
|
*/
|
||
|
classes: [],
|
||
|
|
||
|
/**
|
||
|
* Files to parse for docs
|
||
|
*
|
||
|
* @attribute sources
|
||
|
* @type Array
|
||
|
* @default []
|
||
|
*/
|
||
|
sources: [],
|
||
|
|
||
|
ready: function() {
|
||
|
window.addEventListener('hashchange', this.parseLocationHash.bind(this));
|
||
|
this.parseLocationHash();
|
||
|
},
|
||
|
|
||
|
parseLocationHash: function() {
|
||
|
this.route = window.location.hash.slice(1);
|
||
|
},
|
||
|
|
||
|
routeChanged: function() {
|
||
|
this.validateRoute();
|
||
|
},
|
||
|
|
||
|
validateRoute: function() {
|
||
|
if (this.route) {
|
||
|
this.classes.some(function(c) {
|
||
|
if (c.name === this.route) {
|
||
|
this.data = c;
|
||
|
this.route = '';
|
||
|
return;
|
||
|
}
|
||
|
}, this);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
selectedChanged: function() {
|
||
|
this.data = this.classes[this.selected];
|
||
|
},
|
||
|
|
||
|
parserDataReady: function(event) {
|
||
|
this.assimilateData(event.target.data);
|
||
|
},
|
||
|
|
||
|
assimilateData: function(data) {
|
||
|
this.classes = this.classes.concat(data.classes);
|
||
|
this.classes.sort(function(a, b) {
|
||
|
var na = a && a.name.toLowerCase(), nb = b && b.name.toLowerCase();
|
||
|
return (na < nb) ? -1 : (na == nb) ? 0 : 1;
|
||
|
});
|
||
|
if (!this.data && !this.route && this.classes.length) {
|
||
|
this.data = this.classes[0];
|
||
|
}
|
||
|
if (this.classes.length > 1) {
|
||
|
this.$.toc.style.display = 'block';
|
||
|
}
|
||
|
this.validateRoute();
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
</script>
|
||
|
|
||
|
</polymer-element>
|
||
|
</div>
|
||
|
<div hidden>undefined</div>
|
||
|
|
||
|
<!--
|
||
|
|
||
|
Implements the default landing page for Polymer components.
|
||
|
|
||
|
`<core-component-page>` can render an information page for any component.
|
||
|
Polymer components use this component in `index.html` to provide the standard landing page.
|
||
|
|
||
|
`<core-component-page>` is _vulcanized_, which means it contains all it's dependencies baked in.
|
||
|
Therefore, this component is intended to be used only by itself in a page.
|
||
|
|
||
|
This *-dev package contains the raw source and the dependency manifest necessary
|
||
|
to reconstruct `core-component-page\core-component-page.html` via vulcanize.
|
||
|
|
||
|
`<core-component-page>` will set the page title automatically.
|
||
|
|
||
|
@group Polymer Core Elements
|
||
|
@element core-component-page
|
||
|
|
||
|
-->
|
||
|
|
||
|
<polymer-element name="core-component-page" attributes="moduleName sources" assetpath="../core-component-page-dev/">
|
||
|
|
||
|
<template>
|
||
|
|
||
|
<style>/*
|
||
|
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||
|
Code distributed by Google as part of the polymer project is also
|
||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||
|
*/
|
||
|
|
||
|
:host {
|
||
|
font-family: Arial, sans-serif;
|
||
|
height: 100vh;
|
||
|
}
|
||
|
|
||
|
h2 {
|
||
|
display: inline-block;
|
||
|
margin: 8px 6px;
|
||
|
vertical-align: middle;
|
||
|
}
|
||
|
|
||
|
.choiceB, .choiceC, .choiceD {
|
||
|
/* typography */
|
||
|
color: white;
|
||
|
/* font-size: 14px; */
|
||
|
font-size: 12px;
|
||
|
font-weight: bold;
|
||
|
text-decoration: none;
|
||
|
/* colors / effects */
|
||
|
background-color: #4285F4;
|
||
|
box-shadow: 0 1px 2px 0px rgba(0, 0, 0, 0.1);
|
||
|
box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.1);
|
||
|
border-radius: 2px;
|
||
|
cursor: pointer;
|
||
|
/* metrics */
|
||
|
display: inline-block;
|
||
|
padding: 4px 12px 5px 12px;
|
||
|
margin: 4px 0;
|
||
|
}
|
||
|
|
||
|
.appbar {
|
||
|
background-color: #E91E63;
|
||
|
color: white;
|
||
|
}
|
||
|
</style>
|
||
|
|
||
|
<core-layout vertical=""></core-layout>
|
||
|
|
||
|
<core-toolbar class="appbar">
|
||
|
<span>{{moduleName}}</span>
|
||
|
<a class="choiceC" target="_blank" href="../{{moduleName}}/demo.html">demo</a>
|
||
|
</core-toolbar>
|
||
|
|
||
|
<core-doc-viewer core-flex="" url="{{url}}" sources="{{sources}}"></core-doc-viewer>
|
||
|
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
|
||
|
Polymer('core-component-page', {
|
||
|
|
||
|
moduleName: '',
|
||
|
// TODO(sjmiles): needed this to force Object type for deserialization
|
||
|
sources: [],
|
||
|
|
||
|
ready: function() {
|
||
|
this.moduleName = this.moduleName || this.findModuleName();
|
||
|
},
|
||
|
|
||
|
moduleNameChanged: function() {
|
||
|
document.title = this.moduleName;
|
||
|
this.url = !this.sources.length && this.moduleName ? this.moduleName + '.html' : '';
|
||
|
},
|
||
|
|
||
|
findModuleName: function() {
|
||
|
var path = location.pathname.split('/');
|
||
|
var name = path.pop() || path.pop();
|
||
|
if (name.indexOf('.html') >= 0) {
|
||
|
name = path.pop();
|
||
|
}
|
||
|
return name || '';
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
</script>
|
||
|
|
||
|
</polymer-element>
|