From eea1ca23db336db10e95c9feff5390872af5c358 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Wed, 29 Mar 2017 15:52:01 -0700 Subject: [PATCH] closure advanced compilation --- .eslintrc.json | 2 +- externs/closure-types.js | 718 ++++++++++++++++++++++++ externs/polymer-externs.js | 9 +- gulpfile.js | 61 +- lib/elements/array-selector.html | 22 +- lib/elements/dom-bind.html | 6 + lib/elements/dom-repeat.html | 9 +- lib/legacy/legacy-element-mixin.html | 17 +- lib/mixins/element-mixin.html | 37 +- lib/mixins/gesture-event-listeners.html | 17 +- lib/mixins/mutable-data.html | 26 +- lib/mixins/property-accessors.html | 20 +- lib/mixins/property-effects.html | 28 +- lib/mixins/template-stamp.html | 13 +- lib/utils/async.html | 16 +- lib/utils/boot.html | 16 +- lib/utils/mixin.html | 8 +- lib/utils/render-status.html | 4 +- lib/utils/templatize.html | 7 +- package.json | 4 +- polymer-element.html | 2 + 21 files changed, 966 insertions(+), 76 deletions(-) create mode 100644 externs/closure-types.js diff --git a/.eslintrc.json b/.eslintrc.json index 4ab15499c8..04b84c2059 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -19,6 +19,6 @@ "Polymer": true, "ShadyDOM": true, "ShadyCSS": true, - "goog": true + "JSCompiler_renameProperty": true } } diff --git a/externs/closure-types.js b/externs/closure-types.js new file mode 100644 index 0000000000..b64842134a --- /dev/null +++ b/externs/closure-types.js @@ -0,0 +1,718 @@ + +/** + * @fileoverview Closure types for Polymer mixins + * @externs + * + * This file is generated, do not edit manually + */ +/* eslint-disable no-unused-vars */ + +/** +* @record +*/ +function Polymer_PropertyAccessors(){} +/** +*/ +Polymer_PropertyAccessors.prototype._initializeProperties = function(){}; +/** +* @param {Object} props +*/ +Polymer_PropertyAccessors.prototype._initializeProtoProperties = function(props){}; +/** +* @param {string} attribute +* @param {string} value +*/ +Polymer_PropertyAccessors.prototype._ensureAttribute = function(attribute, value){}; +/** +* @param {string} attribute +* @param {string} value +* @param {*} type +*/ +Polymer_PropertyAccessors.prototype._attributeToProperty = function(attribute, value, type){}; +/** +* @param {string} property +* @param {string=} attribute +* @param {*=} value +*/ +Polymer_PropertyAccessors.prototype._propertyToAttribute = function(property, attribute, value){}; +/** +* @param {Element} node +* @param {*} value +* @param {string} attribute +*/ +Polymer_PropertyAccessors.prototype._valueToNodeAttribute = function(node, value, attribute){}; +/** +* @param {*} value +* @return {(string|undefined)} +*/ +Polymer_PropertyAccessors.prototype._serializeValue = function(value){}; +/** +* @param {string} value +* @param {*} type +* @return {*} +*/ +Polymer_PropertyAccessors.prototype._deserializeValue = function(value, type){}; +/** +* @param {string} property +* @param {boolean=} readOnly +*/ +Polymer_PropertyAccessors.prototype._createPropertyAccessor = function(property, readOnly){}; +/** +* @param {string} property +* @param {*} value +*/ +Polymer_PropertyAccessors.prototype._setProperty = function(property, value){}; +/** +* @param {string} property +* @param {*} value +*/ +Polymer_PropertyAccessors.prototype._setPendingProperty = function(property, value){}; +/** +* @param {string} prop +* @return {boolean} +*/ +Polymer_PropertyAccessors.prototype._isPropertyPending = function(prop){}; +/** +*/ +Polymer_PropertyAccessors.prototype._invalidateProperties = function(){}; +/** +*/ +Polymer_PropertyAccessors.prototype._flushProperties = function(){}; +/** +* @param {Object} currentProps +* @param {Object} changedProps +* @param {Object} oldProps +*/ +Polymer_PropertyAccessors.prototype._propertiesChanged = function(currentProps, changedProps, oldProps){}; +/** +* @param {string} property +* @param {*} value +* @param {*} old +* @return {boolean} +*/ +Polymer_PropertyAccessors.prototype._shouldPropertyChange = function(property, value, old){}; +/** +* @record +*/ +function Polymer_TemplateStamp(){} +/** +* @param {HTMLTemplateElement} template +*/ +Polymer_TemplateStamp.prototype._stampTemplate = function(template){}; +/** +* @param {*} template +*/ +Polymer_TemplateStamp.prototype._parseTemplateAnnotations = function(template){}; +/** +* @param {*} node +* @param {*} eventName +* @param {*} methodName +* @param {*} context +*/ +Polymer_TemplateStamp.prototype._addMethodEventListenerToNode = function(node, eventName, methodName, context){}; +/** +* @param {*} node +* @param {*} eventName +* @param {*} handler +*/ +Polymer_TemplateStamp.prototype._addEventListenerToNode = function(node, eventName, handler){}; +/** +* @param {*} node +* @param {*} eventName +* @param {*} handler +*/ +Polymer_TemplateStamp.prototype._removeEventListenerFromNode = function(node, eventName, handler){}; +/** +* @record +* @extends {Polymer_TemplateStamp} +* @extends {Polymer_PropertyAccessors} +*/ +function Polymer_PropertyEffects(){} +/** +*/ +Polymer_PropertyEffects.prototype._initializeProperties = function(){}; +/** +* @param {*} props +*/ +Polymer_PropertyEffects.prototype._initializeProtoProperties = function(props){}; +/** +* @param {*} property +* @param {string} type +* @param {Object=} effect +*/ +Polymer_PropertyEffects.prototype._addPropertyEffect = function(property, type, effect){}; +/** +* @param {string} property +* @param {string=} type +* @return {boolean} +*/ +Polymer_PropertyEffects.prototype._hasPropertyEffect = function(property, type){}; +/** +* @param {string} property +* @return {boolean} +*/ +Polymer_PropertyEffects.prototype._hasReadOnlyEffect = function(property){}; +/** +* @param {string} property +* @return {boolean} +*/ +Polymer_PropertyEffects.prototype._hasNotifyEffect = function(property){}; +/** +* @param {string} property +* @return {boolean} +*/ +Polymer_PropertyEffects.prototype._hasReflectEffect = function(property){}; +/** +* @param {string} property +* @return {boolean} +*/ +Polymer_PropertyEffects.prototype._hasComputedEffect = function(property){}; +/** +* @param {(string|!Array.<(number|string)>)} path +* @param {*} value +* @param {*} shouldNotify +* @param {boolean=} isPathNotification +* @return {boolean} +*/ +Polymer_PropertyEffects.prototype._setPendingPropertyOrPath = function(path, value, shouldNotify, isPathNotification){}; +/** +* @param {Node} node +* @param {string} prop +* @param {*} value +*/ +Polymer_PropertyEffects.prototype._setUnmanagedPropertyToNode = function(node, prop, value){}; +/** +* @param {*} property +* @param {*} value +* @param {*} shouldNotify +*/ +Polymer_PropertyEffects.prototype._setPendingProperty = function(property, value, shouldNotify){}; +/** +* @param {*} property +* @param {*} value +*/ +Polymer_PropertyEffects.prototype._setProperty = function(property, value){}; +/** +*/ +Polymer_PropertyEffects.prototype._invalidateProperties = function(){}; +/** +* @param {Object} client +*/ +Polymer_PropertyEffects.prototype._enqueueClient = function(client){}; +/** +*/ +Polymer_PropertyEffects.prototype._flushClients = function(){}; +/** +* @param {Object} props +*/ +Polymer_PropertyEffects.prototype.setProperties = function(props){}; +/** +*/ +Polymer_PropertyEffects.prototype._flushProperties = function(){}; +/** +*/ +Polymer_PropertyEffects.prototype.ready = function(){}; +/** +*/ +Polymer_PropertyEffects.prototype._readyClients = function(){}; +/** +* @param {HTMLTemplateElement} template +* @return {DocumentFragment} +*/ +Polymer_PropertyEffects.prototype._stampTemplate = function(template){}; +/** +* @param {*} currentProps +* @param {*} changedProps +* @param {*} oldProps +*/ +Polymer_PropertyEffects.prototype._propertiesChanged = function(currentProps, changedProps, oldProps){}; +/** +* @param {(string|!Array.<(string|number)>)} to +* @param {(string|!Array.<(string|number)>)} from +*/ +Polymer_PropertyEffects.prototype.linkPaths = function(to, from){}; +/** +* @param {(string|!Array.<(string|number)>)} path +*/ +Polymer_PropertyEffects.prototype.unlinkPaths = function(path){}; +/** +* @param {string} path +* @param {Array} splices +*/ +Polymer_PropertyEffects.prototype.notifySplices = function(path, splices){}; +/** +* @param {(string|!Array.<(string|number)>)} path +* @param {Object=} root +* @return {*} +*/ +Polymer_PropertyEffects.prototype.get = function(path, root){}; +/** +* @param {(string|!Array.<(string|number)>)} path +* @param {*} value +* @param {Object=} root +*/ +Polymer_PropertyEffects.prototype.set = function(path, value, root){}; +/** +* @param {string} path +* @param {*} items +* @return {number} +*/ +Polymer_PropertyEffects.prototype.push = function(path, items){}; +/** +* @param {string} path +* @return {*} +*/ +Polymer_PropertyEffects.prototype.pop = function(path){}; +/** +* @param {string} path +* @param {number} start +* @param {number} deleteCount +* @param {*} items +* @return {Array} +*/ +Polymer_PropertyEffects.prototype.splice = function(path, start, deleteCount, items){}; +/** +* @param {string} path +* @return {*} +*/ +Polymer_PropertyEffects.prototype.shift = function(path){}; +/** +* @param {string} path +* @param {*} items +* @return {number} +*/ +Polymer_PropertyEffects.prototype.unshift = function(path, items){}; +/** +* @param {string} path +* @param {*=} value +*/ +Polymer_PropertyEffects.prototype.notifyPath = function(path, value){}; +/** +* @param {string} property +* @param {boolean=} protectedSetter +*/ +Polymer_PropertyEffects.prototype._createReadOnlyProperty = function(property, protectedSetter){}; +/** +* @param {string} property +* @param {string} methodName +* @param {boolean=} dynamicFn +*/ +Polymer_PropertyEffects.prototype._createPropertyObserver = function(property, methodName, dynamicFn){}; +/** +* @param {string} expression +* @param {Object=} dynamicFns +*/ +Polymer_PropertyEffects.prototype._createMethodObserver = function(expression, dynamicFns){}; +/** +* @param {string} property +*/ +Polymer_PropertyEffects.prototype._createNotifyingProperty = function(property){}; +/** +* @param {string} property +*/ +Polymer_PropertyEffects.prototype._createReflectedProperty = function(property){}; +/** +* @param {string} property +* @param {string} expression +* @param {Object=} dynamicFns +*/ +Polymer_PropertyEffects.prototype._createComputedProperty = function(property, expression, dynamicFns){}; +/** +* @param {HTMLTemplateElement} template +* @param {Object=} dynamicFns +*/ +Polymer_PropertyEffects.prototype._bindTemplate = function(template, dynamicFns){}; +/** +* @record +* @extends {Polymer_PropertyEffects} +*/ +function Polymer_ElementMixin(){} +/** +*/ +Polymer_ElementMixin.prototype._initializeProperties = function(){}; +/** +*/ +Polymer_ElementMixin.prototype.connectedCallback = function(){}; +/** +*/ +Polymer_ElementMixin.prototype.disconnectedCallback = function(){}; +/** +*/ +Polymer_ElementMixin.prototype._readyClients = function(){}; +/** +* @param {NodeList} dom +* @return {Node} +*/ +Polymer_ElementMixin.prototype._attachDom = function(dom){}; +/** +* @param {*} name +* @param {*} old +* @param {*} value +*/ +Polymer_ElementMixin.prototype.attributeChangedCallback = function(name, old, value){}; +/** +* @param {Object=} properties +*/ +Polymer_ElementMixin.prototype.updateStyles = function(properties){}; +/** +* @param {string} url +* @param {string=} base +* @return {string} +*/ +Polymer_ElementMixin.prototype.resolveUrl = function(url, base){}; +/** +* @record +*/ +function Polymer_GestureEventListeners(){} +/** +* @param {*} node +* @param {*} eventName +* @param {*} handler +*/ +Polymer_GestureEventListeners.prototype._addEventListenerToNode = function(node, eventName, handler){}; +/** +* @param {*} node +* @param {*} eventName +* @param {*} handler +*/ +Polymer_GestureEventListeners.prototype._removeEventListenerFromNode = function(node, eventName, handler){}; +/** +* @record +* @extends {Polymer_ElementMixin} +* @extends {Polymer_GestureEventListeners} +*/ +function Polymer_LegacyElementMixin(){} +/** +*/ +Polymer_LegacyElementMixin.prototype.created = function(){}; +/** +*/ +Polymer_LegacyElementMixin.prototype.attached = function(){}; +/** +*/ +Polymer_LegacyElementMixin.prototype.detached = function(){}; +/** +*/ +Polymer_LegacyElementMixin.prototype.attributeChanged = function(){}; +/** +*/ +Polymer_LegacyElementMixin.prototype._initializeProperties = function(){}; +/** +*/ +Polymer_LegacyElementMixin.prototype._registered = function(){}; +/** +*/ +Polymer_LegacyElementMixin.prototype.ready = function(){}; +/** +*/ +Polymer_LegacyElementMixin.prototype._ensureAttributes = function(){}; +/** +*/ +Polymer_LegacyElementMixin.prototype._applyListeners = function(){}; +/** +* @param {*} value +* @return {string} +*/ +Polymer_LegacyElementMixin.prototype.serialize = function(value){}; +/** +* @param {string} value +* @param {*} type +*/ +Polymer_LegacyElementMixin.prototype.deserialize = function(value, type){}; +/** +* @param {string} property +* @param {string=} attribute +* @param {*=} value +*/ +Polymer_LegacyElementMixin.prototype.reflectPropertyToAttribute = function(property, attribute, value){}; +/** +* @param {*} value +* @param {string} attribute +* @param {Element} node +*/ +Polymer_LegacyElementMixin.prototype.serializeValueToAttribute = function(value, attribute, node){}; +/** +* @param {Object} prototype +* @param {Object} api +* @return {Object} +*/ +Polymer_LegacyElementMixin.prototype.extend = function(prototype, api){}; +/** +* @param {Object} target +* @param {Object} source +* @return {Object} +*/ +Polymer_LegacyElementMixin.prototype.mixin = function(target, source){}; +/** +* @param {*} object +* @param {*} inherited +*/ +Polymer_LegacyElementMixin.prototype.chainObject = function(object, inherited){}; +/** +* @param {HTMLTemplateElement} template +* @return {DocumentFragment} +*/ +Polymer_LegacyElementMixin.prototype.instanceTemplate = function(template){}; +/** +* @param {string} type +* @param {*=} detail +* @param {Object=} options +* @return {Event} +*/ +Polymer_LegacyElementMixin.prototype.fire = function(type, detail, options){}; +/** +* @param {Element} node +* @param {string} eventName +* @param {string} methodName +*/ +Polymer_LegacyElementMixin.prototype.listen = function(node, eventName, methodName){}; +/** +* @param {Element} node +* @param {string} eventName +* @param {string} methodName +*/ +Polymer_LegacyElementMixin.prototype.unlisten = function(node, eventName, methodName){}; +/** +* @param {String=} direction +* @param {HTMLElement=} node +*/ +Polymer_LegacyElementMixin.prototype.setScrollDirection = function(direction, node){}; +/** +* @param {string} slctr +* @return {Element} +*/ +Polymer_LegacyElementMixin.prototype.$$ = function(slctr){}; +/** +*/ +Polymer_LegacyElementMixin.prototype.distributeContent = function(){}; +/** +* @return {Array.} +*/ +Polymer_LegacyElementMixin.prototype.getEffectiveChildNodes = function(){}; +/** +* @param {string} selector +* @return {Array.} +*/ +Polymer_LegacyElementMixin.prototype.queryDistributedElements = function(selector){}; +/** +* @return {Array.} +*/ +Polymer_LegacyElementMixin.prototype.getEffectiveChildren = function(){}; +/** +* @return {string} +*/ +Polymer_LegacyElementMixin.prototype.getEffectiveTextContent = function(){}; +/** +* @param {string} selector +* @return {Object.} +*/ +Polymer_LegacyElementMixin.prototype.queryEffectiveChildren = function(selector){}; +/** +* @param {string} selector +* @return {Array.} +*/ +Polymer_LegacyElementMixin.prototype.queryAllEffectiveChildren = function(selector){}; +/** +* @param {String=} slctr +* @return {Array.} +*/ +Polymer_LegacyElementMixin.prototype.getContentChildNodes = function(slctr){}; +/** +* @param {String=} slctr +* @return {Array.} +*/ +Polymer_LegacyElementMixin.prototype.getContentChildren = function(slctr){}; +/** +* @param {?Node} node +* @return {Boolean} +*/ +Polymer_LegacyElementMixin.prototype.isLightDescendant = function(node){}; +/** +* @param {HTMLElement=} node +* @return {boolean} +*/ +Polymer_LegacyElementMixin.prototype.isLocalDescendant = function(node){}; +/** +* @param {*} container +* @param {*} shouldObserve +*/ +Polymer_LegacyElementMixin.prototype.scopeSubtree = function(container, shouldObserve){}; +/** +* @param {String} property +* @return {String} +*/ +Polymer_LegacyElementMixin.prototype.getComputedStyleValue = function(property){}; +/** +* @param {String} jobName +* @param {function ()} callback +* @param {number} wait +*/ +Polymer_LegacyElementMixin.prototype.debounce = function(jobName, callback, wait){}; +/** +* @param {String} jobName +* @return {boolean} +*/ +Polymer_LegacyElementMixin.prototype.isDebouncerActive = function(jobName){}; +/** +* @param {String} jobName +*/ +Polymer_LegacyElementMixin.prototype.flushDebouncer = function(jobName){}; +/** +* @param {String} jobName +*/ +Polymer_LegacyElementMixin.prototype.cancelDebouncer = function(jobName){}; +/** +* @param {Function} callback +* @param {number=} waitTime +* @return {number} +*/ +Polymer_LegacyElementMixin.prototype.async = function(callback, waitTime){}; +/** +* @param {number} handle +*/ +Polymer_LegacyElementMixin.prototype.cancelAsync = function(handle){}; +/** +* @param {string} tag +* @param {Object} props +* @return {Element} +*/ +Polymer_LegacyElementMixin.prototype.create = function(tag, props){}; +/** +* @param {string} href +* @param {Function} onload +* @param {Function} onerror +* @param {boolean} optAsync +* @return {HTMLLinkElement} +*/ +Polymer_LegacyElementMixin.prototype.importHref = function(href, onload, onerror, optAsync){}; +/** +* @param {string} selector +* @param {Element=} node +* @return {boolean} +*/ +Polymer_LegacyElementMixin.prototype.elementMatches = function(selector, node){}; +/** +* @param {String} name +* @param {boolean=} bool +* @param {HTMLElement=} node +*/ +Polymer_LegacyElementMixin.prototype.toggleAttribute = function(name, bool, node){}; +/** +* @param {String} name +* @param {boolean=} bool +* @param {HTMLElement=} node +*/ +Polymer_LegacyElementMixin.prototype.toggleClass = function(name, bool, node){}; +/** +* @param {string} transformText +* @param {HTMLElement=} node +*/ +Polymer_LegacyElementMixin.prototype.transform = function(transformText, node){}; +/** +* @param {number} x +* @param {number} y +* @param {number} z +* @param {HTMLElement=} node +*/ +Polymer_LegacyElementMixin.prototype.translate3d = function(x, y, z, node){}; +/** +* @param {(string|!Array.<(number|string)>)} arrayOrPath +* @param {*} item +* @return {Array} +*/ +Polymer_LegacyElementMixin.prototype.arrayDelete = function(arrayOrPath, item){}; +/** +* @param {string} level +* @param {Array} args +*/ +Polymer_LegacyElementMixin.prototype._logger = function(level, args){}; +/** +* @param {*} args +*/ +Polymer_LegacyElementMixin.prototype._log = function(args){}; +/** +* @param {*} args +*/ +Polymer_LegacyElementMixin.prototype._warn = function(args){}; +/** +* @param {*} args +*/ +Polymer_LegacyElementMixin.prototype._error = function(args){}; +/** +* @param {*} args +* @return {string} +*/ +Polymer_LegacyElementMixin.prototype._logf = function(args){}; +/** +* @record +*/ +function Polymer_MutableData(){} +/** +* @param {string} property +* @param {*} value +* @param {*} old +* @return {boolean} +*/ +Polymer_MutableData.prototype._shouldPropertyChange = function(property, value, old){}; +/** +* @record +*/ +function Polymer_OptionalMutableData(){} +/** @type {boolean} */ +Polymer_OptionalMutableData.prototype.mutableData; + +/** +* @param {string} property +* @param {*} value +* @param {*} old +* @return {boolean} +*/ +Polymer_OptionalMutableData.prototype._shouldPropertyChange = function(property, value, old){}; +/** +* @record +*/ +function Polymer_ArraySelectorMixin(){} +/** @type {Array} */ +Polymer_ArraySelectorMixin.prototype.items; + +/** @type {boolean} */ +Polymer_ArraySelectorMixin.prototype.multi; + +/** @type {Object} */ +Polymer_ArraySelectorMixin.prototype.selected; + +/** @type {Object} */ +Polymer_ArraySelectorMixin.prototype.selectedItem; + +/** @type {boolean} */ +Polymer_ArraySelectorMixin.prototype.toggle; + +/** +*/ +Polymer_ArraySelectorMixin.prototype.clearSelection = function(){}; +/** +* @param {*} item +* @return {boolean} +*/ +Polymer_ArraySelectorMixin.prototype.isSelected = function(item){}; +/** +* @param {*} idx +* @return {boolean} +*/ +Polymer_ArraySelectorMixin.prototype.isIndexSelected = function(idx){}; +/** +* @param {*} item +*/ +Polymer_ArraySelectorMixin.prototype.deselect = function(item){}; +/** +* @param {number} idx +*/ +Polymer_ArraySelectorMixin.prototype.deselectIndex = function(idx){}; +/** +* @param {*} item +*/ +Polymer_ArraySelectorMixin.prototype.select = function(item){}; +/** +* @param {number} idx +*/ +Polymer_ArraySelectorMixin.prototype.selectIndex = function(idx){}; \ No newline at end of file diff --git a/externs/polymer-externs.js b/externs/polymer-externs.js index 704f0e359f..b0fb6dba2b 100644 --- a/externs/polymer-externs.js +++ b/externs/polymer-externs.js @@ -7,4 +7,11 @@ * @param {!{is: string}} init * @return {!CustomElement} */ -function Polymer(init){} \ No newline at end of file +function Polymer(init){} + +/** + * @param {string} string + * @param {Object} obj + * @return {string} + */ +function JSCompiler_renameProperty(string, obj) {} \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index c53550742a..e2c09b72cb 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -40,7 +40,7 @@ const ENTRY_POINTS = [POLYMER_LEGACY, POLYMER_ELEMENT]; const polymer = require('polymer-build'); const PolymerProject = polymer.PolymerProject; -const project = new PolymerProject({ shell: DEFAULT_BUILD_TARGET }); +const project = new PolymerProject({ entrypoint: DEFAULT_BUILD_TARGET }); const fork = polymer.forkStream; gulp.task('clean', function() { @@ -75,11 +75,37 @@ class OldNameStream extends Transform { } } +class Log extends Transform { + constructor(prefix = '') { + super({objectMode: true}); + this.prefix = prefix; + } + _transform(file, enc, cb) { + console.log(this.prefix, file.path); + cb(null, file); + } +} + gulp.task('closure', ['clean'], () => { + let entry, splitRx, joinRx; + + function full() { + entry = 'polymer.html'; + splitRx = /polymer\.html_script_\d+\.js$/; + joinRx = /polymer\.html/; + } + + function element() { + entry = 'polymer-element.html'; + splitRx = /polymer-element\.html_script_\d+\.js$/; + joinRx = /polymer-element\.html/; + } + + element(); + const project = new PolymerProject({ - sources: ['./polymer.html'], - shell: './polymer.html' + entrypoint: `./${entry}` }); const closureStream = closure({ @@ -87,9 +113,21 @@ gulp.task('closure', ['clean'], () => { language_in: 'ES6_STRICT', language_out: 'ES5_STRICT', warning_level: 'VERBOSE', - output_wrapper: '(function(){\n%output%\n}).call(self)', + output_wrapper: '(function(){\n%output%\n}).call(self);', + assume_function_wrapper: true, rewrite_polyfills: false, - externs: ['externs/closure-upstream-externs.js', 'externs/webcomponents-externs.js', 'externs/polymer-externs.js'] + new_type_inf: true, + externs: [ + 'externs/closure-upstream-externs.js', + 'externs/webcomponents-externs.js', + 'externs/polymer-externs.js', + 'externs/closure-types.js' + ], + extra_annotation_name: [ + 'polymerMixin', + 'polymerMixinClass', + 'polymerElement' + ] }); const closurePipeline = lazypipe() @@ -105,14 +143,15 @@ gulp.task('closure', ['clean'], () => { // merge the source and dependencies streams to we can analyze the project const mergedFiles = mergeStream(sources, dependencies); + const splitter = new polymer.HtmlSplitter(); return mergedFiles .pipe(project.bundler) - .pipe(project.splitHtml()) - .pipe(gulpif(/polymer\.html_script_\d+\.js$/, closurePipeline())) - .pipe(project.rejoinHtml()) - .pipe(htmlmin({removeComments: true})) - .pipe(gulpif(/polymer\.html/, minimalDocument())) - .pipe(gulpif(/polymer\.html/, size({title: 'closure size', gzip: true, showTotal: false, showFiles: true}))) + .pipe(splitter.split()) + .pipe(gulpif(splitRx, closurePipeline())) + .pipe(splitter.rejoin()) + // .pipe(htmlmin({removeComments: true})) + .pipe(gulpif(joinRx, minimalDocument())) + .pipe(gulpif(joinRx, size({title: 'closure size', gzip: true, showTotal: false, showFiles: true}))) .pipe(gulp.dest(COMPILED_DIR)) }); diff --git a/lib/elements/array-selector.html b/lib/elements/array-selector.html index 5cf7c3c8be..3857ddf10f 100644 --- a/lib/elements/array-selector.html +++ b/lib/elements/array-selector.html @@ -33,8 +33,17 @@ * @polymerMixin * @memberof Polymer */ - let ArraySelectorMixin = Polymer.dedupingMixin(superClass => { - + let ArraySelectorMixin = Polymer.dedupingMixin( + /** + * @template T + * @param {function(new:T)} superClass + */ + function(superClass) { + + /** + * @polymerMixinClass + * @implements {Polymer_ArraySelectorMixin} + */ return class extends superClass { static get properties() { @@ -325,6 +334,13 @@ // export mixin Polymer.ArraySelectorMixin = ArraySelectorMixin; + /** + * @constructor + * @extends {Polymer.Element} + * @implements {Polymer_ArraySelectorMixin} + */ + let baseArraySelector = ArraySelectorMixin(Polymer.Element); + /** * Element implementing the `Polymer.ArraySelector` mixin, which records * dynamic associations between item paths in a master `items` array and a @@ -391,7 +407,7 @@ * @summary Custom element that links paths between an input `items` array and * an output `selected` item or array based on calls to its selection API. */ - class ArraySelector extends ArraySelectorMixin(Polymer.Element) { + class ArraySelector extends baseArraySelector { // Not needed to find template; can be removed once the analyzer // can find the tag name from customElements.define call static get is() { return 'array-selector' } diff --git a/lib/elements/dom-bind.html b/lib/elements/dom-bind.html index d08ca0e37c..a03379219d 100644 --- a/lib/elements/dom-bind.html +++ b/lib/elements/dom-bind.html @@ -16,6 +16,12 @@ (function() { 'use strict'; + /** + * @constructor + * @implements {Polymer_PropertyEffects} + * @implements {Polymer_OptionalMutableData} + * @extends {HTMLElement} + */ const domBindBase = Polymer.OptionalMutableData(Polymer.PropertyEffects(HTMLElement)); /** diff --git a/lib/elements/dom-repeat.html b/lib/elements/dom-repeat.html index 0b7ee3f5f3..7c8d5300f1 100644 --- a/lib/elements/dom-repeat.html +++ b/lib/elements/dom-repeat.html @@ -18,6 +18,13 @@ (function() { 'use strict'; + /** + * @constructor + * @implements {Polymer_OptionalMutableData} + * @extends {Polymer.Element} + */ + const domRepeatBase = Polymer.OptionalMutableData(Polymer.Element); + /** * The `` element will automatically stamp and binds one instance * of template content to each object in a user-provided array. @@ -112,7 +119,7 @@ * @summary Custom element for stamping instance of a template bound to * items in an array. */ - class DomRepeat extends Polymer.OptionalMutableData(Polymer.Element) { + class DomRepeat extends domRepeatBase { // Not needed to find template; can be removed once the analyzer // can find the tag name from customElements.define call diff --git a/lib/legacy/legacy-element-mixin.html b/lib/legacy/legacy-element-mixin.html index 8f67b81ee2..5f22752ee7 100644 --- a/lib/legacy/legacy-element-mixin.html +++ b/lib/legacy/legacy-element-mixin.html @@ -38,8 +38,19 @@ * @memberof Polymer * @summary Element class mixin that provides Polymer's "legacy" API */ - Polymer.LegacyElementMixin = Polymer.dedupingMixin(function(base) { + Polymer.LegacyElementMixin = Polymer.dedupingMixin( + /** + * @template T + * @param {function(new:T)} base + */ + function(base) { + /** + * @constructor + * @extends {base} + * @implements {Polymer_ElementMixin} + * @implements {Polymer_GestureEventListeners} + */ const legacyElementBase = Polymer.GestureEventListeners(Polymer.ElementMixin(base)); /** @@ -53,6 +64,10 @@ 'all': 'auto' }; + /** + * @polymerMixinClass + * @implements {Polymer_LegacyElement} + */ return class LegacyElement extends legacyElementBase { constructor() { diff --git a/lib/mixins/element-mixin.html b/lib/mixins/element-mixin.html index 18d63eaac5..2025b5fad0 100644 --- a/lib/mixins/element-mixin.html +++ b/lib/mixins/element-mixin.html @@ -113,8 +113,18 @@ * @summary Element class mixin that provides the core API for Polymer's * meta-programming features. */ - Polymer.ElementMixin = Polymer.dedupingMixin(function(base) { + Polymer.ElementMixin = Polymer.dedupingMixin( + /** + * @template T + * @param {function(new:T)} base + */ + function(base) { + /** + * @constructor + * @extends {base} + * @implements {Polymer_PropertyEffects} + */ const polymerElementBase = Polymer.PropertyEffects(base); let caseMap = Polymer.CaseMap; @@ -129,9 +139,9 @@ */ function ownPropertiesForClass(klass) { if (!klass.hasOwnProperty( - goog.reflect.objectProperty('__ownProperties', klass))) { + JSCompiler_renameProperty('__ownProperties', klass))) { klass.__ownProperties = - klass.hasOwnProperty(goog.reflect.objectProperty('properties', klass)) ? + klass.hasOwnProperty(JSCompiler_renameProperty('properties', klass)) ? klass.properties : {}; } return klass.__ownProperties; @@ -145,9 +155,9 @@ */ function ownObserversForClass(klass) { if (!klass.hasOwnProperty( - goog.reflect.objectProperty('__ownObservers', klass))) { + JSCompiler_renameProperty('__ownObservers', klass))) { klass.__ownObservers = - klass.hasOwnProperty(goog.reflect.objectProperty('observers', klass)) ? + klass.hasOwnProperty(JSCompiler_renameProperty('observers', klass)) ? klass.observers : []; } return klass.__ownObservers; @@ -182,7 +192,7 @@ */ function propertiesForClass(klass) { if (!klass.hasOwnProperty( - goog.reflect.objectProperty('__classProperties', klass))) { + JSCompiler_renameProperty('__classProperties', klass))) { klass.__classProperties = flattenProperties({}, ownPropertiesForClass(klass)); let superCtor = Object.getPrototypeOf(klass.prototype).constructor; @@ -206,7 +216,7 @@ */ function propertyDefaultsForClass(klass) { if (!klass.hasOwnProperty( - goog.reflect.objectProperty('__classPropertyDefaults', klass))) { + JSCompiler_renameProperty('__classPropertyDefaults', klass))) { klass.__classPropertyDefaults = null; let props = propertiesForClass(klass); for (let p in props) { @@ -226,7 +236,7 @@ * @private */ function hasClassFinalized(klass) { - return klass.hasOwnProperty(goog.reflect.objectProperty('__finalized', klass)); + return klass.hasOwnProperty(JSCompiler_renameProperty('__finalized', klass)); } /** @@ -255,7 +265,7 @@ klass.__finalized = true; let proto = klass.prototype; if (klass.hasOwnProperty( - goog.reflect.objectProperty('is', klass)) && klass.is) { + JSCompiler_renameProperty('is', klass)) && klass.is) { Polymer.telemetry.register(proto); } let props = ownPropertiesForClass(klass); @@ -397,7 +407,7 @@ * Configures an element `proto` to function with a given `template`. * The element name `is` and extends `ext` must be specified for ShadyCSS * style scoping. - * @param {HTMLElement} proto + * @param {Polymer_ElementMixin} proto * @param {HTMLTemplateElement} template * @param {string} baseURI URL against which to resolve urls in * style element cssText. @@ -424,6 +434,7 @@ /** * @polymerMixinClass * @unrestricted + * @implements {Polymer_ElementMixin} */ class PolymerElement extends polymerElementBase { @@ -436,7 +447,7 @@ * @return {Array} Observed attribute list */ static get observedAttributes() { - if (!this.hasOwnProperty(goog.reflect.objectProperty('__observedAttributes', this))) { + if (!this.hasOwnProperty(JSCompiler_renameProperty('__observedAttributes', this))) { let list = []; let properties = propertiesForClass(this); for (let prop in properties) { @@ -503,7 +514,7 @@ * @returns {HTMLTemplateElement|string} */ static get template() { - if (!this.hasOwnProperty(goog.reflect.objectProperty('_template', this))) { + if (!this.hasOwnProperty(JSCompiler_renameProperty('_template', this))) { this._template = Polymer.DomModule.import(this.is, 'template') || // note: implemented so a subclass can retrieve the super // template; call the super impl this way so that `this` points @@ -525,7 +536,7 @@ * @returns {string} */ static get importPath() { - if (!this.hasOwnProperty(goog.reflect.objectProperty('_importPath', this))) { + if (!this.hasOwnProperty(JSCompiler_renameProperty('_importPath', this))) { const module = Polymer.DomModule.import(this.is); this._importPath = module ? module.assetpath : '' || Object.getPrototypeOf(this.prototype).constructor.importPath; diff --git a/lib/mixins/gesture-event-listeners.html b/lib/mixins/gesture-event-listeners.html index 714cddac35..7342df39b0 100644 --- a/lib/mixins/gesture-event-listeners.html +++ b/lib/mixins/gesture-event-listeners.html @@ -31,20 +31,27 @@ * @summary Element class mixin that provides API for adding Polymer's cross-platform * gesture events to nodes */ - Polymer.GestureEventListeners = Polymer.dedupingMixin(function(superClass) { + Polymer.GestureEventListeners = Polymer.dedupingMixin( + /** + * @template T + * @param {function(new:T)} superClass + */ + function(superClass) { + /** + * @polymerMixinClass + * @implements {Polymer_GestureEventListeners} + */ return class GestureEventListeners extends superClass { _addEventListenerToNode(node, eventName, handler) { - if (!gestures.addListener(node, eventName, handler) && - super._addEventListenerToNode) { + if (!gestures.addListener(node, eventName, handler)) { super._addEventListenerToNode(node, eventName, handler); } } _removeEventListenerFromNode(node, eventName, handler) { - if (!gestures.removeListener(node, eventName, handler) && - super._removeEventListenerFromNode) { + if (!gestures.removeListener(node, eventName, handler)) { super._removeEventListenerFromNode(node, eventName, handler); } } diff --git a/lib/mixins/mutable-data.html b/lib/mixins/mutable-data.html index 2cfe3d54d3..6e1b50adf6 100644 --- a/lib/mixins/mutable-data.html +++ b/lib/mixins/mutable-data.html @@ -68,8 +68,17 @@ * @summary Element class mixin to skip strict dirty-checking for objects * and arrays */ - Polymer.MutableData = (superClass) => { + Polymer.MutableData = Polymer.dedupingMixin( + /** + * @template T + * @param {function(new:T)} superClass + */ + function(superClass) { + /** + * @polymerMixinClass + * @implements {Polymer_MutableData} + */ return class MutableData extends superClass { /** * Overrides `Polymer.PropertyEffects` to provide option for skipping @@ -94,7 +103,7 @@ } - }; + }); /** * Element class mixin to add the optional ability to skip strict @@ -133,8 +142,17 @@ * @summary Element class mixin to optionally skip strict dirty-checking * for objects and arrays */ - Polymer.OptionalMutableData = (superClass) => { + Polymer.OptionalMutableData = Polymer.dedupingMixin( + /** + * @template T + * @param {function(new:T)} superClass + */ + function(superClass) { + /** + * @polymerMixinClass + * @implements {Polymer_OptionalMutableData} + */ return class OptionalMutableData extends superClass { static get properties() { @@ -171,7 +189,7 @@ } } - }; + }); // Export for use by legacy behavior Polymer.MutableData._mutablePropertyChange = mutablePropertyChange; diff --git a/lib/mixins/property-accessors.html b/lib/mixins/property-accessors.html index 6555968e7a..7176903953 100644 --- a/lib/mixins/property-accessors.html +++ b/lib/mixins/property-accessors.html @@ -61,7 +61,7 @@ // Adding accessor to proto; save proto's value for instance-time use if (!model.__dataProto) { model.__dataProto = {}; - } else if (!model.hasOwnProperty(goog.reflect.objectProperty('__dataProto', model))) { + } else if (!model.hasOwnProperty(JSCompiler_renameProperty('__dataProto', model))) { model.__dataProto = Object.create(model.__dataProto); } model.__dataProto[property] = value; @@ -88,9 +88,19 @@ * @summary Element class mixin for reacting to property changes from * generated property accessors. */ - Polymer.PropertyAccessors = Polymer.dedupingMixin(function(superClass) { - - return class PropertyAccessors extends superClass { + Polymer.PropertyAccessors = Polymer.dedupingMixin( + /** + * @template T + * @param {function(new:T)} superClass + */ + function(superClass) { + + /** + * @polymerMixinClass + * @implements {Polymer_PropertyAccessors} + * @unrestricted + */ + class PropertyAccessors extends superClass { /** * Generates property accessors for all attributes in the standard @@ -488,6 +498,8 @@ } + return PropertyAccessors; + }); })(); diff --git a/lib/mixins/property-effects.html b/lib/mixins/property-effects.html index de11cd4df3..add97a8900 100644 --- a/lib/mixins/property-effects.html +++ b/lib/mixins/property-effects.html @@ -87,9 +87,10 @@ * on an instance. * * @param {Object} inst The instance with effects to run - * @param {string} type Type of effect to run + * @param {Object} effects * @param {Object} props Bag of current property changes * @param {Object=} oldProps Bag of previous values for changed properties + * @param {boolean=} hasPaths * @private */ function runEffects(inst, effects, props, oldProps, hasPaths) { @@ -109,11 +110,12 @@ * Runs a list of effects for a given property. * * @param {Object} inst The instance with effects to run - * @param {Array} effects Array of effects - * @param {number} id Effect run id used for de-duping effects + * @param {Object} effects Array of effects + * @param {number} dedupeId Effect run id used for de-duping effects * @param {string} prop Name of changed property - * @param {*} value Value of changed property - * @param {*} old Previous value of changed property + * @param {*} props Value of changed property + * @param {*} oldProps Previous value of changed property + * @param {boolean=} hasPaths * @private */ function runEffectsForProperty(inst, effects, dedupeId, prop, props, oldProps, hasPaths) { @@ -1203,13 +1205,25 @@ * @summary Element class mixin that provides meta-programming for Polymer's * template binding and data observation system. */ - Polymer.PropertyEffects = Polymer.dedupingMixin(function(superClass) { + Polymer.PropertyEffects = Polymer.dedupingMixin( + /** + * @template T + * @param {function(new:T)} superClass + */ + function(superClass) { + /** + * @constructor + * @extends {superClass} + * @implements {Polymer_PropertyAccessors} + * @implements {Polymer_TemplateStamp} + */ const propertyEffectsBase = Polymer.TemplateStamp(Polymer.PropertyAccessors(superClass)); /** * @polymerMixinClass * @unrestricted + * @implements {Polymer_PropertyEffects} */ class PropertyEffects extends propertyEffectsBase { @@ -1415,7 +1429,7 @@ // already dirty checked at the point of entry and the underlying // object has already been updated let old = Polymer.Path.get(this, path); - path = /** @type {string} */ Polymer.Path.set(this, path, value); + path = /** @type {string} */ (Polymer.Path.set(this, path, value)); // Use property-accessor's simpler dirty check if (!path || !super._shouldPropertyChange(path, value, old)) { return false; diff --git a/lib/mixins/template-stamp.html b/lib/mixins/template-stamp.html index ac10e38fdd..70fa9921c7 100644 --- a/lib/mixins/template-stamp.html +++ b/lib/mixins/template-stamp.html @@ -450,8 +450,17 @@ * @memberof Polymer * @summary Element class mixin that provides basic template parsing and stamping */ - Polymer.TemplateStamp = Polymer.dedupingMixin(function(superClass) { - + Polymer.TemplateStamp = Polymer.dedupingMixin( + /** + * @template T + * @param {function(new:T)} superClass + */ + function(superClass) { + + /** + * @polymerMixinClass + * @implements {Polymer_TemplateStamp} + */ return class TemplateStamp extends superClass { constructor() { diff --git a/lib/utils/async.html b/lib/utils/async.html index 6bcfbd4b61..1124dda81e 100644 --- a/lib/utils/async.html +++ b/lib/utils/async.html @@ -81,14 +81,14 @@ * * @memberof Polymer.Async.timeOut * @param {Function} fn Callback to run - * @return {*} Handle used for canceling task + * @return {number} Handle used for canceling task */ run: window.setTimeout.bind(window), /** * Cancels a previously enqueued `timeOut` callback. * * @memberof Polymer.Async.timeOut - * @param {*} handle Handle returned from `run` of callback to cancel + * @param {number} handle Handle returned from `run` of callback to cancel */ cancel: window.clearTimeout.bind(window) }, @@ -106,14 +106,14 @@ * * @memberof Polymer.Async.timeOut * @param {Function} fn Callback to run - * @return {*} Handle used for canceling task + * @return {number} Handle used for canceling task */ run: window.requestAnimationFrame.bind(window), /** * Cancels a previously enqueued `animationFrame` callback. * * @memberof Polymer.Async.timeOut - * @param {*} handle Handle returned from `run` of callback to cancel + * @param {number} handle Handle returned from `run` of callback to cancel */ cancel: window.cancelAnimationFrame.bind(window) }, @@ -131,8 +131,8 @@ * Enqueues a function called at `requestIdleCallback` timing. * * @memberof Polymer.Async.timeOut - * @param {Function} fn Callback to run - * @return {*} Handle used for canceling task + * @param {function(IdleDeadline)} fn Callback to run + * @return {number} Handle used for canceling task */ run(fn) { return window.requestIdleCallback ? @@ -143,7 +143,7 @@ * Cancels a previously enqueued `idlePeriod` callback. * * @memberof Polymer.Async.timeOut - * @param {*} handle Handle returned from `run` of callback to cancel + * @param {number} handle Handle returned from `run` of callback to cancel */ cancel(timer) { return window.cancelIdleCallback ? @@ -183,7 +183,7 @@ /** * Cancels a previously enqueued `microTask` callback. * - * @param {*} handle Handle returned from `run` of callback to cancel + * @param {number} handle Handle returned from `run` of callback to cancel */ cancel(handle) { const idx = handle - microtaskLastHandle; diff --git a/lib/utils/boot.html b/lib/utils/boot.html index 677a295466..e6c0258fbb 100644 --- a/lib/utils/boot.html +++ b/lib/utils/boot.html @@ -29,22 +29,22 @@ } // To be plugged by legacy implementation if loaded - window.Polymer._polymerFn = function() { + /** + * @param {Object} info + */ + window.Polymer._polymerFn = function(info) { // eslint-disable-line no-unused-vars throw new Error('Load polymer.html to use the Polymer() function.'); } window.Polymer.version = '2.0-preview'; /* eslint-disable no-unused-vars */ /* - When using Closure Compiler, goog.reflect.objectProperty(property, object) is replaced by the munged name for object[property] + When using Closure Compiler, JSCompiler_renameProperty(property, object) is replaced by the munged name for object[property] We cannot alias this function, so we have to use a small shim that has the same behavior when not compiling. */ - window.goog = window.goog || {}; - window.goog.reflect = window.goog.reflect || { - objectProperty(s, o) { - return s; - } - }; + window.JSCompiler_renameProperty = function(prop, obj) { + return prop; + } /* eslint-enable */ })(); diff --git a/lib/utils/mixin.html b/lib/utils/mixin.html index 85a04b0e3a..51ac437c52 100644 --- a/lib/utils/mixin.html +++ b/lib/utils/mixin.html @@ -22,6 +22,9 @@ /** * Given a mixin producing function, memoize applications of mixin to base * @private + * @template T + * @param {T} mixin + * @return {T} */ function cachingMixin(mixin) { return function(base) { @@ -44,8 +47,9 @@ * applications. * * @memberof Polymer - * @param {function} mixin ES6 class expression mixin to wrap - * @return {function} Wrapped mixin that deduplicates and memoizes + * @template {T} + * @param {T} mixin ES6 class expression mixin to wrap + * @return {T} Wrapped mixin that deduplicates and memoizes * mixin applications to base */ Polymer.dedupingMixin = function(mixin) { diff --git a/lib/utils/render-status.html b/lib/utils/render-status.html index 1713b57d57..9703356c21 100644 --- a/lib/utils/render-status.html +++ b/lib/utils/render-status.html @@ -75,7 +75,7 @@ * * @memberof Polymer.RenderStatus * @param {*} context Context object the callback function will be bound to - * @param {function} callback Callback function + * @param {function()} callback Callback function * @param {Array} args An array of arguments to call the callback function with */ beforeNextRender: function(context, callback, args) { @@ -96,7 +96,7 @@ * * @memberof Polymer.RenderStatus * @param {*} context Context object the callback function will be bound to - * @param {function} callback Callback function + * @param {function()} callback Callback function * @param {Array} args An array of arguments to call the callback function with */ afterNextRender: function(context, callback, args) { diff --git a/lib/utils/templatize.html b/lib/utils/templatize.html index ad1008aee3..c2376016d0 100644 --- a/lib/utils/templatize.html +++ b/lib/utils/templatize.html @@ -40,7 +40,12 @@ } // Base class for TemplateInstance's - class TemplateInstanceBase extends Polymer.PropertyEffects(class{}) { + /** + * @constructor + * @mixes {Polymer_PropertyEffects} + */ + const base = Polymer.PropertyEffects(class {}); + class TemplateInstanceBase extends base { constructor(props) { super(); this._configureProperties(props); diff --git a/package.json b/package.json index 5abd923fb5..49406cea4b 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "del": "^2.2.1", "dom5": "^1.3.1", "eslint-plugin-html": "^1.3.0", - "google-closure-compiler": "^20161201.0.0", + "google-closure-compiler": "^20170218.0.0", "gulp": "^3.9.1", "gulp-audit": "^1.0.0", "gulp-babel": "^6.1.2", @@ -24,7 +24,7 @@ "gulp-vulcanize": "^6.0.1", "lazypipe": "^1.0.1", "merge-stream": "^1.0.1", - "polymer-build": "^0.6.0", + "polymer-build": "0.8.3", "run-sequence": "^1.1.0", "through2": "^2.0.0", "web-component-tester": "^6.0.0-prerelease.4" diff --git a/polymer-element.html b/polymer-element.html index 9a9db27b65..1dac595c13 100644 --- a/polymer-element.html +++ b/polymer-element.html @@ -19,6 +19,8 @@ * * @polymerElement * @memberof Polymer + * @constructor + * @implements {Polymer_ElementMixin} * @extends HTMLElement * @mixes Polymer.ElementMixin * @summary Custom element base class that provides the core API for Polymer's