Revert "Build Observatory with runtime"
This reverts commit 76df7b3c1bf83c08d3994d61df4c9c530fadb4e5. This commit breaks dartium compilation. BUG= R=ricow@google.com Review URL: https://codereview.chromium.org//839543002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@42619 260f80e4-7a28-3924-810f-c04153c831b5
|
@ -14,7 +14,7 @@
|
||||||
'filepath': 'tools/',
|
'filepath': 'tools/',
|
||||||
},
|
},
|
||||||
'observatory': {
|
'observatory': {
|
||||||
'filepath': 'runtime/observatory/',
|
'filepath': 'runtime/bin/vmservice/',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
'<!@(["python", "../tools/list_pkg_directories.py", '
|
'<!@(["python", "../tools/list_pkg_directories.py", '
|
||||||
'"../third_party/pkg"])',
|
'"../third_party/pkg"])',
|
||||||
'<!@(["python", "../tools/list_pkg_directories.py", '
|
'<!@(["python", "../tools/list_pkg_directories.py", '
|
||||||
'"../runtime"])',
|
'"../runtime/bin/vmservice"])',
|
||||||
'../sdk/lib/_internal',
|
'../sdk/lib/_internal',
|
||||||
'../site/try',
|
'../site/try',
|
||||||
],
|
],
|
||||||
|
|
|
@ -13,8 +13,6 @@
|
||||||
'snapshot_in_cc_file': 'snapshot_in.cc',
|
'snapshot_in_cc_file': 'snapshot_in.cc',
|
||||||
'snapshot_bin_file': '<(gen_source_dir)/snapshot_gen.bin',
|
'snapshot_bin_file': '<(gen_source_dir)/snapshot_gen.bin',
|
||||||
'resources_cc_file': '<(gen_source_dir)/resources_gen.cc',
|
'resources_cc_file': '<(gen_source_dir)/resources_gen.cc',
|
||||||
'bootstrap_resources_cc_file':
|
|
||||||
'<(gen_source_dir)/bootstrap_resources_gen.cc',
|
|
||||||
'snapshot_cc_file': '<(gen_source_dir)/snapshot_gen.cc',
|
'snapshot_cc_file': '<(gen_source_dir)/snapshot_gen.cc',
|
||||||
},
|
},
|
||||||
'targets': [
|
'targets': [
|
||||||
|
@ -360,9 +358,6 @@
|
||||||
'target_name': 'generate_resources_cc_file',
|
'target_name': 'generate_resources_cc_file',
|
||||||
'type': 'none',
|
'type': 'none',
|
||||||
'toolsets':['host'],
|
'toolsets':['host'],
|
||||||
'dependencies': [
|
|
||||||
'build_observatory#host',
|
|
||||||
],
|
|
||||||
'includes': [
|
'includes': [
|
||||||
'resources_sources.gypi',
|
'resources_sources.gypi',
|
||||||
],
|
],
|
||||||
|
@ -372,8 +367,8 @@
|
||||||
'inputs': [
|
'inputs': [
|
||||||
'../tools/create_resources.py',
|
'../tools/create_resources.py',
|
||||||
# The following two files are used to trigger a rebuild.
|
# The following two files are used to trigger a rebuild.
|
||||||
'<(PRODUCT_DIR)/observatory/deployed/web/index.html',
|
'vmservice/observatory/deployed/web/index.html',
|
||||||
'<(PRODUCT_DIR)/observatory/deployed/web/index.html_bootstrap.dart.js',
|
'vmservice/observatory/deployed/web/index.html_bootstrap.dart.js',
|
||||||
'<@(_sources)',
|
'<@(_sources)',
|
||||||
],
|
],
|
||||||
'outputs': [
|
'outputs': [
|
||||||
|
@ -387,45 +382,13 @@
|
||||||
'--inner_namespace', 'bin',
|
'--inner_namespace', 'bin',
|
||||||
'--table_name', 'service_bin',
|
'--table_name', 'service_bin',
|
||||||
'--root_prefix', 'bin/',
|
'--root_prefix', 'bin/',
|
||||||
'--client_root', '<(PRODUCT_DIR)/observatory/deployed/web/',
|
'--client_root', 'bin/vmservice/observatory/deployed/',
|
||||||
'<@(_sources)'
|
'<@(_sources)'
|
||||||
],
|
],
|
||||||
'message': 'Generating ''<(resources_cc_file)'' file.'
|
'message': 'Generating ''<(resources_cc_file)'' file.'
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
'target_name': 'generate_bootstrap_resources_cc_file',
|
|
||||||
'type': 'none',
|
|
||||||
'toolsets':['host'],
|
|
||||||
'includes': [
|
|
||||||
'resources_sources.gypi',
|
|
||||||
],
|
|
||||||
'actions': [
|
|
||||||
{
|
|
||||||
'action_name': 'generate_resources_cc',
|
|
||||||
'inputs': [
|
|
||||||
'../tools/create_resources.py',
|
|
||||||
'<@(_sources)',
|
|
||||||
],
|
|
||||||
'outputs': [
|
|
||||||
'<(bootstrap_resources_cc_file)',
|
|
||||||
],
|
|
||||||
'action': [
|
|
||||||
'python',
|
|
||||||
'tools/create_resources.py',
|
|
||||||
'--output', '<(bootstrap_resources_cc_file)',
|
|
||||||
'--outer_namespace', 'dart',
|
|
||||||
'--inner_namespace', 'bin',
|
|
||||||
'--table_name', 'service_bin',
|
|
||||||
'--root_prefix', 'bin/',
|
|
||||||
'<@(_sources)'
|
|
||||||
],
|
|
||||||
'message':
|
|
||||||
'Generating ''<(bootstrap_resources_cc_file)'' file.'
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
# dart binary with a snapshot of corelibs built in.
|
# dart binary with a snapshot of corelibs built in.
|
||||||
'target_name': 'dart',
|
'target_name': 'dart',
|
||||||
|
@ -434,7 +397,6 @@
|
||||||
'libdart',
|
'libdart',
|
||||||
'libdart_builtin',
|
'libdart_builtin',
|
||||||
'libdart_io',
|
'libdart_io',
|
||||||
'build_observatory#host',
|
|
||||||
'generate_snapshot_file#host',
|
'generate_snapshot_file#host',
|
||||||
'generate_resources_cc_file#host',
|
'generate_resources_cc_file#host',
|
||||||
],
|
],
|
||||||
|
@ -477,61 +439,6 @@
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
# dart binary built for the host. It does not use a snapshot
|
|
||||||
# and does not include Observatory.
|
|
||||||
'target_name': 'dart_bootstrap',
|
|
||||||
'type': 'executable',
|
|
||||||
'toolsets':['host'],
|
|
||||||
'dependencies': [
|
|
||||||
'libdart_withcore',
|
|
||||||
'libdart_builtin',
|
|
||||||
'libdart_io',
|
|
||||||
'generate_bootstrap_resources_cc_file#host',
|
|
||||||
],
|
|
||||||
'include_dirs': [
|
|
||||||
'..',
|
|
||||||
],
|
|
||||||
'sources': [
|
|
||||||
'main.cc',
|
|
||||||
'builtin.cc',
|
|
||||||
'builtin_natives.cc',
|
|
||||||
'builtin.h',
|
|
||||||
'io_natives.h',
|
|
||||||
'vmservice.h',
|
|
||||||
'vmservice_impl.cc',
|
|
||||||
'vmservice_impl.h',
|
|
||||||
# Include generated source files.
|
|
||||||
'<(builtin_cc_file)',
|
|
||||||
'<(io_cc_file)',
|
|
||||||
'<(io_patch_cc_file)',
|
|
||||||
'<(bootstrap_resources_cc_file)',
|
|
||||||
'snapshot_empty.cc',
|
|
||||||
],
|
|
||||||
'conditions': [
|
|
||||||
['OS=="win"', {
|
|
||||||
'link_settings': {
|
|
||||||
'libraries': [ '-lws2_32.lib', '-lRpcrt4.lib', '-lwinmm.lib' ],
|
|
||||||
},
|
|
||||||
# Generate an import library on Windows, by exporting a function.
|
|
||||||
# Extensions use this import library to link to the API in dart.exe.
|
|
||||||
'msvs_settings': {
|
|
||||||
'VCLinkerTool': {
|
|
||||||
'AdditionalOptions': [ '/EXPORT:Dart_True' ],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}],
|
|
||||||
],
|
|
||||||
'configurations': {
|
|
||||||
'Dart_Linux_Base': {
|
|
||||||
# Have the linker add all symbols to the dynamic symbol table
|
|
||||||
# so that extensions can look them up dynamically in the binary.
|
|
||||||
'ldflags': [
|
|
||||||
'-rdynamic',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
# dart binary without any snapshot built in.
|
# dart binary without any snapshot built in.
|
||||||
'target_name': 'dart_no_snapshot',
|
'target_name': 'dart_no_snapshot',
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
bootstrap_css
|
bootstrap_css
|
||||||
out
|
out
|
||||||
build
|
build
|
||||||
.pub
|
|
39
runtime/bin/vmservice/observatory/HACKING.txt
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
Dart Observatory Developer Guide
|
||||||
|
---
|
||||||
|
|
||||||
|
Assumptions:
|
||||||
|
You are running pub from the latest dev channel release of Dart Editor.
|
||||||
|
|
||||||
|
During development you do not need to run dart2js or rebuild the VM (unless
|
||||||
|
you are also making changes to the backend). While you're working on your
|
||||||
|
feature follow the steps:
|
||||||
|
|
||||||
|
1. Open runtime/bin/vmservice/observatory in the Dart Editor
|
||||||
|
2. Run pub upgrade
|
||||||
|
3. Run dart --observe script.dart
|
||||||
|
4. Run index.html in Dartium
|
||||||
|
|
||||||
|
At this point you should see the initial Observatory UI and that
|
||||||
|
it is communicating with the VM you launched in step 3.
|
||||||
|
|
||||||
|
Continue to develop and iterate until you're ready to upload your change
|
||||||
|
for review. Upload your change and get an LGTM.
|
||||||
|
|
||||||
|
5. Run pub build
|
||||||
|
6. Run ./deploy.sh
|
||||||
|
|
||||||
|
Note: If you run pub from within the editor you need to make sure that it runs
|
||||||
|
in release mode (--mode=release), i.e., output is minified and does not include
|
||||||
|
any .dart source files.
|
||||||
|
|
||||||
|
At this point you should rebuild your VM and:
|
||||||
|
|
||||||
|
7. Launch dart --observe script.dart
|
||||||
|
|
||||||
|
In a non-Dart enabled browser navigate to localhost:8181 and ensure
|
||||||
|
that your feature works after being compiled to JavaScript.
|
||||||
|
|
||||||
|
8. Ensure the vm, standalone, and observatory unit tests still pass:
|
||||||
|
python tools/test.py --mode=debug --arch=ia32 --compiler=none --runtime=vm vm/cc standalone/vmservice vmservice
|
||||||
|
|
||||||
|
9. Commit your change
|
34
runtime/bin/vmservice/observatory/deploy.sh
Executable file
|
@ -0,0 +1,34 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# This script copies the build outputs produced by `pub build` to
|
||||||
|
# the deployed directory.
|
||||||
|
|
||||||
|
if [ ! -d "build" ]; then
|
||||||
|
echo "Please run pub build first"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "deployed" ]; then
|
||||||
|
echo "Run this script from the observatory directory"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
EXCLUDE="--exclude bootstrap_css"
|
||||||
|
EXCLUDE="$EXCLUDE --exclude *.map"
|
||||||
|
EXCLUDE="$EXCLUDE --exclude *.concat.js"
|
||||||
|
EXCLUDE="$EXCLUDE --exclude *.scriptUrls"
|
||||||
|
EXCLUDE="$EXCLUDE --exclude *.precompiled.js"
|
||||||
|
EXCLUDE="$EXCLUDE --exclude main.*"
|
||||||
|
EXCLUDE="$EXCLUDE --exclude unittest"
|
||||||
|
EXCLUDE="$EXCLUDE --exclude *_buildLogs*"
|
||||||
|
|
||||||
|
# For some reason...
|
||||||
|
#
|
||||||
|
# EXCLUDE="$EXCLUDE --exclude *~"
|
||||||
|
#
|
||||||
|
# ..doesn't work to exclude emacs auto-save files. I'm sure it is
|
||||||
|
# something silly, but, in the meantime, solve the problem with a
|
||||||
|
# hammer.
|
||||||
|
find build -type f | grep ~$ | xargs rm
|
||||||
|
|
||||||
|
rsync -av --progress build/web/ deployed/web/ $EXCLUDE
|
4
runtime/bin/vmservice/observatory/deployed/web/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
*.precompiled.js
|
||||||
|
*.scriptUrls
|
||||||
|
main.*
|
||||||
|
!packages/
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
4897
runtime/bin/vmservice/observatory/deployed/web/index.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"experimental_bootstrap":false,"script_ids":[["observatory","lib/src/elements/curly_block.dart"],["observatory","lib/src/elements/observatory_element.dart"],["observatory","lib/src/elements/service_ref.dart"],["observatory","lib/src/elements/instance_ref.dart"],["observatory","lib/src/elements/action_link.dart"],["observatory","lib/src/elements/nav_bar.dart"],["observatory","lib/src/elements/breakpoint_list.dart"],["observatory","lib/src/elements/class_ref.dart"],["observatory","lib/src/elements/class_tree.dart"],["observatory","lib/src/elements/error_ref.dart"],["observatory","lib/src/elements/eval_box.dart"],["observatory","lib/src/elements/eval_link.dart"],["observatory","lib/src/elements/field_ref.dart"],["observatory","lib/src/elements/function_ref.dart"],["observatory","lib/src/elements/library_ref.dart"],["observatory","lib/src/elements/script_inset.dart"],["observatory","lib/src/elements/script_ref.dart"],["observatory","lib/src/elements/class_view.dart"],["observatory","lib/src/elements/code_ref.dart"],["observatory","lib/src/elements/code_view.dart"],["observatory","lib/src/elements/debugger.dart"],["observatory","lib/src/elements/error_view.dart"],["observatory","lib/src/elements/field_view.dart"],["observatory","lib/src/elements/flag_list.dart"],["observatory","lib/src/elements/function_view.dart"],["observatory","lib/src/elements/heap_map.dart"],["observatory","lib/src/elements/io_view.dart"],["observatory","lib/src/elements/isolate_ref.dart"],["observatory","lib/src/elements/isolate_summary.dart"],["observatory","lib/src/elements/isolate_view.dart"],["observatory","lib/src/elements/inbound_reference.dart"],["observatory","lib/src/elements/object_common.dart"],["observatory","lib/src/elements/context_ref.dart"],["observatory","lib/src/elements/instance_view.dart"],["observatory","lib/src/elements/json_view.dart"],["observatory","lib/src/elements/library_view.dart"],["observatory","lib/src/elements/metrics.dart"],["observatory","lib/src/elements/object_view.dart"],["observatory","lib/src/elements/context_view.dart"],["observatory","lib/src/elements/heap_profile.dart"],["observatory","lib/src/elements/sliding_checkbox.dart"],["observatory","lib/src/elements/isolate_profile.dart"],["observatory","lib/src/elements/script_view.dart"],["observatory","lib/src/elements/vm_view.dart"],["observatory","lib/src/elements/service_view.dart"],["observatory","lib/src/elements/observatory_application.dart"],["observatory","lib/src/elements/service_exception_view.dart"],["observatory","lib/src/elements/service_error_view.dart"],["observatory","lib/src/elements/vm_connect.dart"],["observatory","lib/src/elements/vm_ref.dart"],["observatory","web/main.dart"]]}
|
4897
runtime/bin/vmservice/observatory/deployed/web/index_devtools.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"experimental_bootstrap":false,"script_ids":[["observatory","lib/src/elements/curly_block.dart"],["observatory","lib/src/elements/observatory_element.dart"],["observatory","lib/src/elements/service_ref.dart"],["observatory","lib/src/elements/instance_ref.dart"],["observatory","lib/src/elements/action_link.dart"],["observatory","lib/src/elements/nav_bar.dart"],["observatory","lib/src/elements/breakpoint_list.dart"],["observatory","lib/src/elements/class_ref.dart"],["observatory","lib/src/elements/class_tree.dart"],["observatory","lib/src/elements/error_ref.dart"],["observatory","lib/src/elements/eval_box.dart"],["observatory","lib/src/elements/eval_link.dart"],["observatory","lib/src/elements/field_ref.dart"],["observatory","lib/src/elements/function_ref.dart"],["observatory","lib/src/elements/library_ref.dart"],["observatory","lib/src/elements/script_inset.dart"],["observatory","lib/src/elements/script_ref.dart"],["observatory","lib/src/elements/class_view.dart"],["observatory","lib/src/elements/code_ref.dart"],["observatory","lib/src/elements/code_view.dart"],["observatory","lib/src/elements/debugger.dart"],["observatory","lib/src/elements/error_view.dart"],["observatory","lib/src/elements/field_view.dart"],["observatory","lib/src/elements/flag_list.dart"],["observatory","lib/src/elements/function_view.dart"],["observatory","lib/src/elements/heap_map.dart"],["observatory","lib/src/elements/io_view.dart"],["observatory","lib/src/elements/isolate_ref.dart"],["observatory","lib/src/elements/isolate_summary.dart"],["observatory","lib/src/elements/isolate_view.dart"],["observatory","lib/src/elements/inbound_reference.dart"],["observatory","lib/src/elements/object_common.dart"],["observatory","lib/src/elements/context_ref.dart"],["observatory","lib/src/elements/instance_view.dart"],["observatory","lib/src/elements/json_view.dart"],["observatory","lib/src/elements/library_view.dart"],["observatory","lib/src/elements/metrics.dart"],["observatory","lib/src/elements/object_view.dart"],["observatory","lib/src/elements/context_view.dart"],["observatory","lib/src/elements/heap_profile.dart"],["observatory","lib/src/elements/sliding_checkbox.dart"],["observatory","lib/src/elements/isolate_profile.dart"],["observatory","lib/src/elements/script_view.dart"],["observatory","lib/src/elements/vm_view.dart"],["observatory","lib/src/elements/service_view.dart"],["observatory","lib/src/elements/observatory_application.dart"],["observatory","lib/src/elements/service_exception_view.dart"],["observatory","lib/src/elements/service_error_view.dart"],["observatory","lib/src/elements/vm_connect.dart"],["observatory","lib/src/elements/vm_ref.dart"],["observatory","web/main.dart"]]}
|
|
@ -0,0 +1,32 @@
|
||||||
|
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
||||||
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
// Bootstrap support for Dart scripts on the page as this script.
|
||||||
|
if (navigator.userAgent.indexOf('(Dart)') === -1) {
|
||||||
|
// TODO:
|
||||||
|
// - Support in-browser compilation.
|
||||||
|
// - Handle inline Dart scripts.
|
||||||
|
|
||||||
|
// Fall back to compiled JS. Run through all the scripts and
|
||||||
|
// replace them if they have a type that indicate that they source
|
||||||
|
// in Dart code (type="application/dart").
|
||||||
|
var scripts = document.getElementsByTagName("script");
|
||||||
|
var length = scripts.length;
|
||||||
|
for (var i = 0; i < length; ++i) {
|
||||||
|
if (scripts[i].type == "application/dart") {
|
||||||
|
// Remap foo.dart to foo.dart.js.
|
||||||
|
if (scripts[i].src && scripts[i].src != '') {
|
||||||
|
var script = document.createElement('script');
|
||||||
|
script.src = scripts[i].src.replace(/\.dart(?=\?|$)/, '.dart.js');
|
||||||
|
var parent = scripts[i].parentNode;
|
||||||
|
// TODO(vsm): Find a solution for issue 8455 that works with more
|
||||||
|
// than one script.
|
||||||
|
document.currentScript = script;
|
||||||
|
parent.replaceChild(script, scripts[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
|
@ -0,0 +1,9 @@
|
||||||
|
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
||||||
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// TODO(jmesserly): remove this script after a deprecation period.
|
||||||
|
if (typeof console == "object" && typeof console.warn == "function") {
|
||||||
|
console.warn('<script src="packages/browser/interop.js"> is no longer ' +
|
||||||
|
'needed for dart:js. See http://pub.dartlang.org/packages/browser.');
|
||||||
|
}
|
|
@ -0,0 +1,984 @@
|
||||||
|
// Copyright (c) 2012 The Polymer Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
if (typeof WeakMap === 'undefined') {
|
||||||
|
(function() {
|
||||||
|
var defineProperty = Object.defineProperty;
|
||||||
|
var counter = Date.now() % 1e9;
|
||||||
|
|
||||||
|
var WeakMap = function() {
|
||||||
|
this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__');
|
||||||
|
};
|
||||||
|
|
||||||
|
WeakMap.prototype = {
|
||||||
|
set: function(key, value) {
|
||||||
|
var entry = key[this.name];
|
||||||
|
if (entry && entry[0] === key)
|
||||||
|
entry[1] = value;
|
||||||
|
else
|
||||||
|
defineProperty(key, this.name, {value: [key, value], writable: true});
|
||||||
|
},
|
||||||
|
get: function(key) {
|
||||||
|
var entry;
|
||||||
|
return (entry = key[this.name]) && entry[0] === key ?
|
||||||
|
entry[1] : undefined;
|
||||||
|
},
|
||||||
|
delete: function(key) {
|
||||||
|
this.set(key, undefined);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.WeakMap = WeakMap;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
window.CustomElements = window.CustomElements || {flags:{}};
|
||||||
|
(function(scope){
|
||||||
|
|
||||||
|
var logFlags = window.logFlags || {};
|
||||||
|
var IMPORT_LINK_TYPE = window.HTMLImports ? HTMLImports.IMPORT_LINK_TYPE : 'none';
|
||||||
|
|
||||||
|
// walk the subtree rooted at node, applying 'find(element, data)' function
|
||||||
|
// to each element
|
||||||
|
// if 'find' returns true for 'element', do not search element's subtree
|
||||||
|
function findAll(node, find, data) {
|
||||||
|
var e = node.firstElementChild;
|
||||||
|
if (!e) {
|
||||||
|
e = node.firstChild;
|
||||||
|
while (e && e.nodeType !== Node.ELEMENT_NODE) {
|
||||||
|
e = e.nextSibling;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (e) {
|
||||||
|
if (find(e, data) !== true) {
|
||||||
|
findAll(e, find, data);
|
||||||
|
}
|
||||||
|
e = e.nextElementSibling;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// walk all shadowRoots on a given node.
|
||||||
|
function forRoots(node, cb) {
|
||||||
|
var root = node.shadowRoot;
|
||||||
|
while(root) {
|
||||||
|
forSubtree(root, cb);
|
||||||
|
root = root.olderShadowRoot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// walk the subtree rooted at node, including descent into shadow-roots,
|
||||||
|
// applying 'cb' to each element
|
||||||
|
function forSubtree(node, cb) {
|
||||||
|
//logFlags.dom && node.childNodes && node.childNodes.length && console.group('subTree: ', node);
|
||||||
|
findAll(node, function(e) {
|
||||||
|
if (cb(e)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
forRoots(e, cb);
|
||||||
|
});
|
||||||
|
forRoots(node, cb);
|
||||||
|
//logFlags.dom && node.childNodes && node.childNodes.length && console.groupEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
// manage lifecycle on added node
|
||||||
|
function added(node) {
|
||||||
|
if (upgrade(node)) {
|
||||||
|
insertedNode(node);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
inserted(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
// manage lifecycle on added node's subtree only
|
||||||
|
function addedSubtree(node) {
|
||||||
|
forSubtree(node, function(e) {
|
||||||
|
if (added(e)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// manage lifecycle on added node and it's subtree
|
||||||
|
function addedNode(node) {
|
||||||
|
return added(node) || addedSubtree(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
// upgrade custom elements at node, if applicable
|
||||||
|
function upgrade(node) {
|
||||||
|
if (!node.__upgraded__ && node.nodeType === Node.ELEMENT_NODE) {
|
||||||
|
var type = node.getAttribute('is') || node.localName;
|
||||||
|
var definition = scope.registry[type];
|
||||||
|
if (definition) {
|
||||||
|
logFlags.dom && console.group('upgrade:', node.localName);
|
||||||
|
scope.upgrade(node);
|
||||||
|
logFlags.dom && console.groupEnd();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function insertedNode(node) {
|
||||||
|
inserted(node);
|
||||||
|
if (inDocument(node)) {
|
||||||
|
forSubtree(node, function(e) {
|
||||||
|
inserted(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO(sorvell): on platforms without MutationObserver, mutations may not be
|
||||||
|
// reliable and therefore attached/detached are not reliable.
|
||||||
|
// To make these callbacks less likely to fail, we defer all inserts and removes
|
||||||
|
// to give a chance for elements to be inserted into dom.
|
||||||
|
// This ensures attachedCallback fires for elements that are created and
|
||||||
|
// immediately added to dom.
|
||||||
|
var hasPolyfillMutations = (!window.MutationObserver ||
|
||||||
|
(window.MutationObserver === window.JsMutationObserver));
|
||||||
|
scope.hasPolyfillMutations = hasPolyfillMutations;
|
||||||
|
|
||||||
|
var isPendingMutations = false;
|
||||||
|
var pendingMutations = [];
|
||||||
|
function deferMutation(fn) {
|
||||||
|
pendingMutations.push(fn);
|
||||||
|
if (!isPendingMutations) {
|
||||||
|
isPendingMutations = true;
|
||||||
|
var async = (window.Platform && window.Platform.endOfMicrotask) ||
|
||||||
|
setTimeout;
|
||||||
|
async(takeMutations);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function takeMutations() {
|
||||||
|
isPendingMutations = false;
|
||||||
|
var $p = pendingMutations;
|
||||||
|
for (var i=0, l=$p.length, p; (i<l) && (p=$p[i]); i++) {
|
||||||
|
p();
|
||||||
|
}
|
||||||
|
pendingMutations = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function inserted(element) {
|
||||||
|
if (hasPolyfillMutations) {
|
||||||
|
deferMutation(function() {
|
||||||
|
_inserted(element);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
_inserted(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(sjmiles): if there are descents into trees that can never have inDocument(*) true, fix this
|
||||||
|
function _inserted(element) {
|
||||||
|
// TODO(sjmiles): it's possible we were inserted and removed in the space
|
||||||
|
// of one microtask, in which case we won't be 'inDocument' here
|
||||||
|
// But there are other cases where we are testing for inserted without
|
||||||
|
// specific knowledge of mutations, and must test 'inDocument' to determine
|
||||||
|
// whether to call inserted
|
||||||
|
// If we can factor these cases into separate code paths we can have
|
||||||
|
// better diagnostics.
|
||||||
|
// TODO(sjmiles): when logging, do work on all custom elements so we can
|
||||||
|
// track behavior even when callbacks not defined
|
||||||
|
//console.log('inserted: ', element.localName);
|
||||||
|
if (element.attachedCallback || element.detachedCallback || (element.__upgraded__ && logFlags.dom)) {
|
||||||
|
logFlags.dom && console.group('inserted:', element.localName);
|
||||||
|
if (inDocument(element)) {
|
||||||
|
element.__inserted = (element.__inserted || 0) + 1;
|
||||||
|
// if we are in a 'removed' state, bluntly adjust to an 'inserted' state
|
||||||
|
if (element.__inserted < 1) {
|
||||||
|
element.__inserted = 1;
|
||||||
|
}
|
||||||
|
// if we are 'over inserted', squelch the callback
|
||||||
|
if (element.__inserted > 1) {
|
||||||
|
logFlags.dom && console.warn('inserted:', element.localName,
|
||||||
|
'insert/remove count:', element.__inserted)
|
||||||
|
} else if (element.attachedCallback) {
|
||||||
|
logFlags.dom && console.log('inserted:', element.localName);
|
||||||
|
element.attachedCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logFlags.dom && console.groupEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removedNode(node) {
|
||||||
|
removed(node);
|
||||||
|
forSubtree(node, function(e) {
|
||||||
|
removed(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function removed(element) {
|
||||||
|
if (hasPolyfillMutations) {
|
||||||
|
deferMutation(function() {
|
||||||
|
_removed(element);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
_removed(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _removed(element) {
|
||||||
|
// TODO(sjmiles): temporary: do work on all custom elements so we can track
|
||||||
|
// behavior even when callbacks not defined
|
||||||
|
if (element.attachedCallback || element.detachedCallback || (element.__upgraded__ && logFlags.dom)) {
|
||||||
|
logFlags.dom && console.group('removed:', element.localName);
|
||||||
|
if (!inDocument(element)) {
|
||||||
|
element.__inserted = (element.__inserted || 0) - 1;
|
||||||
|
// if we are in a 'inserted' state, bluntly adjust to an 'removed' state
|
||||||
|
if (element.__inserted > 0) {
|
||||||
|
element.__inserted = 0;
|
||||||
|
}
|
||||||
|
// if we are 'over removed', squelch the callback
|
||||||
|
if (element.__inserted < 0) {
|
||||||
|
logFlags.dom && console.warn('removed:', element.localName,
|
||||||
|
'insert/remove count:', element.__inserted)
|
||||||
|
} else if (element.detachedCallback) {
|
||||||
|
element.detachedCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logFlags.dom && console.groupEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SD polyfill intrustion due mainly to the fact that 'document'
|
||||||
|
// is not entirely wrapped
|
||||||
|
function wrapIfNeeded(node) {
|
||||||
|
return window.ShadowDOMPolyfill ? ShadowDOMPolyfill.wrapIfNeeded(node)
|
||||||
|
: node;
|
||||||
|
}
|
||||||
|
|
||||||
|
function inDocument(element) {
|
||||||
|
var p = element;
|
||||||
|
var doc = wrapIfNeeded(document);
|
||||||
|
while (p) {
|
||||||
|
if (p == doc) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
p = p.parentNode || p.host;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function watchShadow(node) {
|
||||||
|
if (node.shadowRoot && !node.shadowRoot.__watched) {
|
||||||
|
logFlags.dom && console.log('watching shadow-root for: ', node.localName);
|
||||||
|
// watch all unwatched roots...
|
||||||
|
var root = node.shadowRoot;
|
||||||
|
while (root) {
|
||||||
|
watchRoot(root);
|
||||||
|
root = root.olderShadowRoot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function watchRoot(root) {
|
||||||
|
if (!root.__watched) {
|
||||||
|
observe(root);
|
||||||
|
root.__watched = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handler(mutations) {
|
||||||
|
//
|
||||||
|
if (logFlags.dom) {
|
||||||
|
var mx = mutations[0];
|
||||||
|
if (mx && mx.type === 'childList' && mx.addedNodes) {
|
||||||
|
if (mx.addedNodes) {
|
||||||
|
var d = mx.addedNodes[0];
|
||||||
|
while (d && d !== document && !d.host) {
|
||||||
|
d = d.parentNode;
|
||||||
|
}
|
||||||
|
var u = d && (d.URL || d._URL || (d.host && d.host.localName)) || '';
|
||||||
|
u = u.split('/?').shift().split('/').pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.group('mutations (%d) [%s]', mutations.length, u || '');
|
||||||
|
}
|
||||||
|
//
|
||||||
|
mutations.forEach(function(mx) {
|
||||||
|
//logFlags.dom && console.group('mutation');
|
||||||
|
if (mx.type === 'childList') {
|
||||||
|
forEach(mx.addedNodes, function(n) {
|
||||||
|
//logFlags.dom && console.log(n.localName);
|
||||||
|
if (!n.localName) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// nodes added may need lifecycle management
|
||||||
|
addedNode(n);
|
||||||
|
});
|
||||||
|
// removed nodes may need lifecycle management
|
||||||
|
forEach(mx.removedNodes, function(n) {
|
||||||
|
//logFlags.dom && console.log(n.localName);
|
||||||
|
if (!n.localName) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
removedNode(n);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//logFlags.dom && console.groupEnd();
|
||||||
|
});
|
||||||
|
logFlags.dom && console.groupEnd();
|
||||||
|
};
|
||||||
|
|
||||||
|
var observer = new MutationObserver(handler);
|
||||||
|
|
||||||
|
function takeRecords() {
|
||||||
|
// TODO(sjmiles): ask Raf why we have to call handler ourselves
|
||||||
|
handler(observer.takeRecords());
|
||||||
|
takeMutations();
|
||||||
|
}
|
||||||
|
|
||||||
|
var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
|
||||||
|
|
||||||
|
function observe(inRoot) {
|
||||||
|
observer.observe(inRoot, {childList: true, subtree: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
function observeDocument(doc) {
|
||||||
|
observe(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
function upgradeDocument(doc) {
|
||||||
|
logFlags.dom && console.group('upgradeDocument: ', (doc.baseURI).split('/').pop());
|
||||||
|
addedNode(doc);
|
||||||
|
logFlags.dom && console.groupEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
function upgradeDocumentTree(doc) {
|
||||||
|
doc = wrapIfNeeded(doc);
|
||||||
|
upgradeDocument(doc);
|
||||||
|
//console.log('upgradeDocumentTree: ', (doc.baseURI).split('/').pop());
|
||||||
|
// upgrade contained imported documents
|
||||||
|
var imports = doc.querySelectorAll('link[rel=' + IMPORT_LINK_TYPE + ']');
|
||||||
|
for (var i=0, l=imports.length, n; (i<l) && (n=imports[i]); i++) {
|
||||||
|
if (n.import && n.import.__parsed) {
|
||||||
|
upgradeDocumentTree(n.import);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// exports
|
||||||
|
scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
|
||||||
|
scope.watchShadow = watchShadow;
|
||||||
|
scope.upgradeDocumentTree = upgradeDocumentTree;
|
||||||
|
scope.upgradeAll = addedNode;
|
||||||
|
scope.upgradeSubtree = addedSubtree;
|
||||||
|
|
||||||
|
scope.observeDocument = observeDocument;
|
||||||
|
scope.upgradeDocument = upgradeDocument;
|
||||||
|
|
||||||
|
scope.takeRecords = takeRecords;
|
||||||
|
|
||||||
|
})(window.CustomElements);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements `document.register`
|
||||||
|
* @module CustomElements
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Polyfilled extensions to the `document` object.
|
||||||
|
* @class Document
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function(scope) {
|
||||||
|
|
||||||
|
// imports
|
||||||
|
|
||||||
|
if (!scope) {
|
||||||
|
scope = window.CustomElements = {flags:{}};
|
||||||
|
}
|
||||||
|
var flags = scope.flags;
|
||||||
|
|
||||||
|
// native document.registerElement?
|
||||||
|
|
||||||
|
var hasNative = Boolean(document.registerElement);
|
||||||
|
// TODO(sorvell): See https://github.com/Polymer/polymer/issues/399
|
||||||
|
// we'll address this by defaulting to CE polyfill in the presence of the SD
|
||||||
|
// polyfill. This will avoid spamming excess attached/detached callbacks.
|
||||||
|
// If there is a compelling need to run CE native with SD polyfill,
|
||||||
|
// we'll need to fix this issue.
|
||||||
|
var useNative = !flags.register && hasNative && !window.ShadowDOMPolyfill;
|
||||||
|
|
||||||
|
if (useNative) {
|
||||||
|
|
||||||
|
// stub
|
||||||
|
var nop = function() {};
|
||||||
|
|
||||||
|
// exports
|
||||||
|
scope.registry = {};
|
||||||
|
scope.upgradeElement = nop;
|
||||||
|
|
||||||
|
scope.watchShadow = nop;
|
||||||
|
scope.upgrade = nop;
|
||||||
|
scope.upgradeAll = nop;
|
||||||
|
scope.upgradeSubtree = nop;
|
||||||
|
scope.observeDocument = nop;
|
||||||
|
scope.upgradeDocument = nop;
|
||||||
|
scope.takeRecords = nop;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a custom tag name with the document.
|
||||||
|
*
|
||||||
|
* When a registered element is created, a `readyCallback` method is called
|
||||||
|
* in the scope of the element. The `readyCallback` method can be specified on
|
||||||
|
* either `options.prototype` or `options.lifecycle` with the latter taking
|
||||||
|
* precedence.
|
||||||
|
*
|
||||||
|
* @method register
|
||||||
|
* @param {String} name The tag name to register. Must include a dash ('-'),
|
||||||
|
* for example 'x-component'.
|
||||||
|
* @param {Object} options
|
||||||
|
* @param {String} [options.extends]
|
||||||
|
* (_off spec_) Tag name of an element to extend (or blank for a new
|
||||||
|
* element). This parameter is not part of the specification, but instead
|
||||||
|
* is a hint for the polyfill because the extendee is difficult to infer.
|
||||||
|
* Remember that the input prototype must chain to the extended element's
|
||||||
|
* prototype (or HTMLElement.prototype) regardless of the value of
|
||||||
|
* `extends`.
|
||||||
|
* @param {Object} options.prototype The prototype to use for the new
|
||||||
|
* element. The prototype must inherit from HTMLElement.
|
||||||
|
* @param {Object} [options.lifecycle]
|
||||||
|
* Callbacks that fire at important phases in the life of the custom
|
||||||
|
* element.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* FancyButton = document.registerElement("fancy-button", {
|
||||||
|
* extends: 'button',
|
||||||
|
* prototype: Object.create(HTMLButtonElement.prototype, {
|
||||||
|
* readyCallback: {
|
||||||
|
* value: function() {
|
||||||
|
* console.log("a fancy-button was created",
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* })
|
||||||
|
* });
|
||||||
|
* @return {Function} Constructor for the newly registered type.
|
||||||
|
*/
|
||||||
|
function register(name, options) {
|
||||||
|
//console.warn('document.registerElement("' + name + '", ', options, ')');
|
||||||
|
// construct a defintion out of options
|
||||||
|
// TODO(sjmiles): probably should clone options instead of mutating it
|
||||||
|
var definition = options || {};
|
||||||
|
if (!name) {
|
||||||
|
// TODO(sjmiles): replace with more appropriate error (EricB can probably
|
||||||
|
// offer guidance)
|
||||||
|
throw new Error('document.registerElement: first argument `name` must not be empty');
|
||||||
|
}
|
||||||
|
if (name.indexOf('-') < 0) {
|
||||||
|
// TODO(sjmiles): replace with more appropriate error (EricB can probably
|
||||||
|
// offer guidance)
|
||||||
|
throw new Error('document.registerElement: first argument (\'name\') must contain a dash (\'-\'). Argument provided was \'' + String(name) + '\'.');
|
||||||
|
}
|
||||||
|
// elements may only be registered once
|
||||||
|
if (getRegisteredDefinition(name)) {
|
||||||
|
throw new Error('DuplicateDefinitionError: a type with name \'' + String(name) + '\' is already registered');
|
||||||
|
}
|
||||||
|
// must have a prototype, default to an extension of HTMLElement
|
||||||
|
// TODO(sjmiles): probably should throw if no prototype, check spec
|
||||||
|
if (!definition.prototype) {
|
||||||
|
// TODO(sjmiles): replace with more appropriate error (EricB can probably
|
||||||
|
// offer guidance)
|
||||||
|
throw new Error('Options missing required prototype property');
|
||||||
|
}
|
||||||
|
// record name
|
||||||
|
definition.__name = name.toLowerCase();
|
||||||
|
// ensure a lifecycle object so we don't have to null test it
|
||||||
|
definition.lifecycle = definition.lifecycle || {};
|
||||||
|
// build a list of ancestral custom elements (for native base detection)
|
||||||
|
// TODO(sjmiles): we used to need to store this, but current code only
|
||||||
|
// uses it in 'resolveTagName': it should probably be inlined
|
||||||
|
definition.ancestry = ancestry(definition.extends);
|
||||||
|
// extensions of native specializations of HTMLElement require localName
|
||||||
|
// to remain native, and use secondary 'is' specifier for extension type
|
||||||
|
resolveTagName(definition);
|
||||||
|
// some platforms require modifications to the user-supplied prototype
|
||||||
|
// chain
|
||||||
|
resolvePrototypeChain(definition);
|
||||||
|
// overrides to implement attributeChanged callback
|
||||||
|
overrideAttributeApi(definition.prototype);
|
||||||
|
// 7.1.5: Register the DEFINITION with DOCUMENT
|
||||||
|
registerDefinition(definition.__name, definition);
|
||||||
|
// 7.1.7. Run custom element constructor generation algorithm with PROTOTYPE
|
||||||
|
// 7.1.8. Return the output of the previous step.
|
||||||
|
definition.ctor = generateConstructor(definition);
|
||||||
|
definition.ctor.prototype = definition.prototype;
|
||||||
|
// force our .constructor to be our actual constructor
|
||||||
|
definition.prototype.constructor = definition.ctor;
|
||||||
|
// if initial parsing is complete
|
||||||
|
if (scope.ready || scope.performedInitialDocumentUpgrade) {
|
||||||
|
// upgrade any pre-existing nodes of this type
|
||||||
|
scope.upgradeDocumentTree(document);
|
||||||
|
}
|
||||||
|
return definition.ctor;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ancestry(extnds) {
|
||||||
|
var extendee = getRegisteredDefinition(extnds);
|
||||||
|
if (extendee) {
|
||||||
|
return ancestry(extendee.extends).concat([extendee]);
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveTagName(definition) {
|
||||||
|
// if we are explicitly extending something, that thing is our
|
||||||
|
// baseTag, unless it represents a custom component
|
||||||
|
var baseTag = definition.extends;
|
||||||
|
// if our ancestry includes custom components, we only have a
|
||||||
|
// baseTag if one of them does
|
||||||
|
for (var i=0, a; (a=definition.ancestry[i]); i++) {
|
||||||
|
baseTag = a.is && a.tag;
|
||||||
|
}
|
||||||
|
// our tag is our baseTag, if it exists, and otherwise just our name
|
||||||
|
definition.tag = baseTag || definition.__name;
|
||||||
|
if (baseTag) {
|
||||||
|
// if there is a base tag, use secondary 'is' specifier
|
||||||
|
definition.is = definition.__name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolvePrototypeChain(definition) {
|
||||||
|
// if we don't support __proto__ we need to locate the native level
|
||||||
|
// prototype for precise mixing in
|
||||||
|
if (!Object.__proto__) {
|
||||||
|
// default prototype
|
||||||
|
var nativePrototype = HTMLElement.prototype;
|
||||||
|
// work out prototype when using type-extension
|
||||||
|
if (definition.is) {
|
||||||
|
var inst = document.createElement(definition.tag);
|
||||||
|
nativePrototype = Object.getPrototypeOf(inst);
|
||||||
|
}
|
||||||
|
// ensure __proto__ reference is installed at each point on the prototype
|
||||||
|
// chain.
|
||||||
|
// NOTE: On platforms without __proto__, a mixin strategy is used instead
|
||||||
|
// of prototype swizzling. In this case, this generated __proto__ provides
|
||||||
|
// limited support for prototype traversal.
|
||||||
|
var proto = definition.prototype, ancestor;
|
||||||
|
while (proto && (proto !== nativePrototype)) {
|
||||||
|
var ancestor = Object.getPrototypeOf(proto);
|
||||||
|
proto.__proto__ = ancestor;
|
||||||
|
proto = ancestor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// cache this in case of mixin
|
||||||
|
definition.native = nativePrototype;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SECTION 4
|
||||||
|
|
||||||
|
function instantiate(definition) {
|
||||||
|
// 4.a.1. Create a new object that implements PROTOTYPE
|
||||||
|
// 4.a.2. Let ELEMENT by this new object
|
||||||
|
//
|
||||||
|
// the custom element instantiation algorithm must also ensure that the
|
||||||
|
// output is a valid DOM element with the proper wrapper in place.
|
||||||
|
//
|
||||||
|
return upgrade(domCreateElement(definition.tag), definition);
|
||||||
|
}
|
||||||
|
|
||||||
|
function upgrade(element, definition) {
|
||||||
|
// some definitions specify an 'is' attribute
|
||||||
|
if (definition.is) {
|
||||||
|
element.setAttribute('is', definition.is);
|
||||||
|
}
|
||||||
|
// remove 'unresolved' attr, which is a standin for :unresolved.
|
||||||
|
element.removeAttribute('unresolved');
|
||||||
|
// make 'element' implement definition.prototype
|
||||||
|
implement(element, definition);
|
||||||
|
// flag as upgraded
|
||||||
|
element.__upgraded__ = true;
|
||||||
|
// there should never be a shadow root on element at this point
|
||||||
|
// we require child nodes be upgraded before `created`
|
||||||
|
scope.upgradeSubtree(element);
|
||||||
|
// lifecycle management
|
||||||
|
created(element);
|
||||||
|
// OUTPUT
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
function implement(element, definition) {
|
||||||
|
// prototype swizzling is best
|
||||||
|
if (Object.__proto__) {
|
||||||
|
element.__proto__ = definition.prototype;
|
||||||
|
} else {
|
||||||
|
// where above we can re-acquire inPrototype via
|
||||||
|
// getPrototypeOf(Element), we cannot do so when
|
||||||
|
// we use mixin, so we install a magic reference
|
||||||
|
customMixin(element, definition.prototype, definition.native);
|
||||||
|
|
||||||
|
// Dart note: make sure we pick up the right constructor.
|
||||||
|
// dart2js depends on this for dart:mirrors caching to work.
|
||||||
|
// See tests/html/custom/mirrors_test.dart
|
||||||
|
element.constructor = definition.prototype.constructor;
|
||||||
|
element.__proto__ = definition.prototype;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function customMixin(inTarget, inSrc, inNative) {
|
||||||
|
// TODO(sjmiles): 'used' allows us to only copy the 'youngest' version of
|
||||||
|
// any property. This set should be precalculated. We also need to
|
||||||
|
// consider this for supporting 'super'.
|
||||||
|
var used = {};
|
||||||
|
// start with inSrc
|
||||||
|
var p = inSrc;
|
||||||
|
// sometimes the default is HTMLUnknownElement.prototype instead of
|
||||||
|
// HTMLElement.prototype, so we add a test
|
||||||
|
// the idea is to avoid mixing in native prototypes, so adding
|
||||||
|
// the second test is WLOG
|
||||||
|
while (p !== inNative && p !== HTMLUnknownElement.prototype) {
|
||||||
|
var keys = Object.getOwnPropertyNames(p);
|
||||||
|
for (var i=0, k; k=keys[i]; i++) {
|
||||||
|
if (!used[k]) {
|
||||||
|
Object.defineProperty(inTarget, k,
|
||||||
|
Object.getOwnPropertyDescriptor(p, k));
|
||||||
|
used[k] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p = Object.getPrototypeOf(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function created(element) {
|
||||||
|
// invoke createdCallback
|
||||||
|
if (element.createdCallback) {
|
||||||
|
element.createdCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// attribute watching
|
||||||
|
|
||||||
|
function overrideAttributeApi(prototype) {
|
||||||
|
// overrides to implement callbacks
|
||||||
|
// TODO(sjmiles): should support access via .attributes NamedNodeMap
|
||||||
|
// TODO(sjmiles): preserves user defined overrides, if any
|
||||||
|
if (prototype.setAttribute._polyfilled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var setAttribute = prototype.setAttribute;
|
||||||
|
prototype.setAttribute = function(name, value) {
|
||||||
|
changeAttribute.call(this, name, value, setAttribute);
|
||||||
|
}
|
||||||
|
var removeAttribute = prototype.removeAttribute;
|
||||||
|
prototype.removeAttribute = function(name) {
|
||||||
|
changeAttribute.call(this, name, null, removeAttribute);
|
||||||
|
}
|
||||||
|
prototype.setAttribute._polyfilled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/
|
||||||
|
// index.html#dfn-attribute-changed-callback
|
||||||
|
function changeAttribute(name, value, operation) {
|
||||||
|
var oldValue = this.getAttribute(name);
|
||||||
|
operation.apply(this, arguments);
|
||||||
|
var newValue = this.getAttribute(name);
|
||||||
|
if (this.attributeChangedCallback
|
||||||
|
&& (newValue !== oldValue)) {
|
||||||
|
this.attributeChangedCallback(name, oldValue, newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// element registry (maps tag names to definitions)
|
||||||
|
|
||||||
|
var registry = {};
|
||||||
|
|
||||||
|
function getRegisteredDefinition(name) {
|
||||||
|
if (name) {
|
||||||
|
return registry[name.toLowerCase()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerDefinition(name, definition) {
|
||||||
|
if (registry[name]) {
|
||||||
|
throw new Error('a type with that name is already registered.');
|
||||||
|
}
|
||||||
|
registry[name] = definition;
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateConstructor(definition) {
|
||||||
|
return function() {
|
||||||
|
return instantiate(definition);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function createElement(tag, typeExtension) {
|
||||||
|
// TODO(sjmiles): ignore 'tag' when using 'typeExtension', we could
|
||||||
|
// error check it, or perhaps there should only ever be one argument
|
||||||
|
var definition = getRegisteredDefinition(typeExtension || tag);
|
||||||
|
if (definition) {
|
||||||
|
if (tag == definition.tag && typeExtension == definition.is) {
|
||||||
|
return new definition.ctor();
|
||||||
|
}
|
||||||
|
// Handle empty string for type extension.
|
||||||
|
if (!typeExtension && !definition.is) {
|
||||||
|
return new definition.ctor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeExtension) {
|
||||||
|
var element = createElement(tag);
|
||||||
|
element.setAttribute('is', typeExtension);
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
var element = domCreateElement(tag);
|
||||||
|
// Custom tags should be HTMLElements even if not upgraded.
|
||||||
|
if (tag.indexOf('-') >= 0) {
|
||||||
|
implement(element, HTMLElement);
|
||||||
|
}
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
function upgradeElement(element) {
|
||||||
|
if (!element.__upgraded__ && (element.nodeType === Node.ELEMENT_NODE)) {
|
||||||
|
var is = element.getAttribute('is');
|
||||||
|
var definition = registry[is || element.localName];
|
||||||
|
if (definition) {
|
||||||
|
if (is && definition.tag == element.localName) {
|
||||||
|
return upgrade(element, definition);
|
||||||
|
} else if (!is && !definition.extends) {
|
||||||
|
return upgrade(element, definition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cloneNode(deep) {
|
||||||
|
// call original clone
|
||||||
|
var n = domCloneNode.call(this, deep);
|
||||||
|
// upgrade the element and subtree
|
||||||
|
scope.upgradeAll(n);
|
||||||
|
// return the clone
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
// capture native createElement before we override it
|
||||||
|
|
||||||
|
var domCreateElement = document.createElement.bind(document);
|
||||||
|
|
||||||
|
// capture native cloneNode before we override it
|
||||||
|
|
||||||
|
var domCloneNode = Node.prototype.cloneNode;
|
||||||
|
|
||||||
|
// exports
|
||||||
|
|
||||||
|
document.registerElement = register;
|
||||||
|
document.createElement = createElement; // override
|
||||||
|
Node.prototype.cloneNode = cloneNode; // override
|
||||||
|
|
||||||
|
scope.registry = registry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upgrade an element to a custom element. Upgrading an element
|
||||||
|
* causes the custom prototype to be applied, an `is` attribute
|
||||||
|
* to be attached (as needed), and invocation of the `readyCallback`.
|
||||||
|
* `upgrade` does nothing if the element is already upgraded, or
|
||||||
|
* if it matches no registered custom tag name.
|
||||||
|
*
|
||||||
|
* @method ugprade
|
||||||
|
* @param {Element} element The element to upgrade.
|
||||||
|
* @return {Element} The upgraded element.
|
||||||
|
*/
|
||||||
|
scope.upgrade = upgradeElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bc
|
||||||
|
document.register = document.registerElement;
|
||||||
|
|
||||||
|
scope.hasNative = hasNative;
|
||||||
|
scope.useNative = useNative;
|
||||||
|
|
||||||
|
})(window.CustomElements);
|
||||||
|
|
||||||
|
(function(scope) {
|
||||||
|
|
||||||
|
// import
|
||||||
|
|
||||||
|
var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
|
||||||
|
|
||||||
|
// highlander object for parsing a document tree
|
||||||
|
|
||||||
|
var parser = {
|
||||||
|
selectors: [
|
||||||
|
'link[rel=' + IMPORT_LINK_TYPE + ']'
|
||||||
|
],
|
||||||
|
map: {
|
||||||
|
link: 'parseLink'
|
||||||
|
},
|
||||||
|
parse: function(inDocument) {
|
||||||
|
if (!inDocument.__parsed) {
|
||||||
|
// only parse once
|
||||||
|
inDocument.__parsed = true;
|
||||||
|
// all parsable elements in inDocument (depth-first pre-order traversal)
|
||||||
|
var elts = inDocument.querySelectorAll(parser.selectors);
|
||||||
|
// for each parsable node type, call the mapped parsing method
|
||||||
|
forEach(elts, function(e) {
|
||||||
|
parser[parser.map[e.localName]](e);
|
||||||
|
});
|
||||||
|
// upgrade all upgradeable static elements, anything dynamically
|
||||||
|
// created should be caught by observer
|
||||||
|
CustomElements.upgradeDocument(inDocument);
|
||||||
|
// observe document for dom changes
|
||||||
|
CustomElements.observeDocument(inDocument);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
parseLink: function(linkElt) {
|
||||||
|
// imports
|
||||||
|
if (isDocumentLink(linkElt)) {
|
||||||
|
this.parseImport(linkElt);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
parseImport: function(linkElt) {
|
||||||
|
if (linkElt.import) {
|
||||||
|
parser.parse(linkElt.import);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function isDocumentLink(inElt) {
|
||||||
|
return (inElt.localName === 'link'
|
||||||
|
&& inElt.getAttribute('rel') === IMPORT_LINK_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
|
||||||
|
|
||||||
|
// exports
|
||||||
|
|
||||||
|
scope.parser = parser;
|
||||||
|
scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
|
||||||
|
|
||||||
|
})(window.CustomElements);
|
||||||
|
(function(scope){
|
||||||
|
|
||||||
|
// bootstrap parsing
|
||||||
|
function bootstrap() {
|
||||||
|
// parse document
|
||||||
|
CustomElements.parser.parse(document);
|
||||||
|
// one more pass before register is 'live'
|
||||||
|
CustomElements.upgradeDocument(document);
|
||||||
|
CustomElements.performedInitialDocumentUpgrade = true;
|
||||||
|
// choose async
|
||||||
|
var async = window.Platform && Platform.endOfMicrotask ?
|
||||||
|
Platform.endOfMicrotask :
|
||||||
|
setTimeout;
|
||||||
|
async(function() {
|
||||||
|
// set internal 'ready' flag, now document.registerElement will trigger
|
||||||
|
// synchronous upgrades
|
||||||
|
CustomElements.ready = true;
|
||||||
|
// capture blunt profiling data
|
||||||
|
CustomElements.readyTime = Date.now();
|
||||||
|
if (window.HTMLImports) {
|
||||||
|
CustomElements.elapsed = CustomElements.readyTime - HTMLImports.readyTime;
|
||||||
|
}
|
||||||
|
// notify the system that we are bootstrapped
|
||||||
|
document.dispatchEvent(
|
||||||
|
new CustomEvent('WebComponentsReady', {bubbles: true})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// CustomEvent shim for IE
|
||||||
|
if (typeof window.CustomEvent !== 'function') {
|
||||||
|
window.CustomEvent = function(inType) {
|
||||||
|
var e = document.createEvent('HTMLEvents');
|
||||||
|
e.initEvent(inType, true, true);
|
||||||
|
return e;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// When loading at readyState complete time (or via flag), boot custom elements
|
||||||
|
// immediately.
|
||||||
|
// If relevant, HTMLImports must already be loaded.
|
||||||
|
if (document.readyState === 'complete' || scope.flags.eager) {
|
||||||
|
bootstrap();
|
||||||
|
// When loading at readyState interactive time, bootstrap only if HTMLImports
|
||||||
|
// are not pending. Also avoid IE as the semantics of this state are unreliable.
|
||||||
|
} else if (document.readyState === 'interactive' && !window.attachEvent &&
|
||||||
|
(!window.HTMLImports || window.HTMLImports.ready)) {
|
||||||
|
bootstrap();
|
||||||
|
// When loading at other readyStates, wait for the appropriate DOM event to
|
||||||
|
// bootstrap.
|
||||||
|
} else {
|
||||||
|
var loadEvent = window.HTMLImports && !HTMLImports.ready
|
||||||
|
? 'HTMLImportsLoaded'
|
||||||
|
: document.readyState == 'loading' ? 'DOMContentLoaded' : 'load';
|
||||||
|
window.addEventListener(loadEvent, bootstrap);
|
||||||
|
}
|
||||||
|
|
||||||
|
})(window.CustomElements);
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
// Patch to allow custom element and shadow dom to work together, from:
|
||||||
|
// https://github.com/Polymer/platform-dev/blob/60ece8c323c5d9325cbfdfd6e8cd180d4f38a3bc/src/patches-shadowdom-polyfill.js
|
||||||
|
// include .host reference
|
||||||
|
if (HTMLElement.prototype.createShadowRoot) {
|
||||||
|
var originalCreateShadowRoot = HTMLElement.prototype.createShadowRoot;
|
||||||
|
HTMLElement.prototype.createShadowRoot = function() {
|
||||||
|
var root = originalCreateShadowRoot.call(this);
|
||||||
|
root.host = this;
|
||||||
|
CustomElements.watchShadow(this);
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Patch to allow custom elements and shadow dom to work together, from:
|
||||||
|
// https://github.com/Polymer/platform-dev/blob/2bb9c56d90f9ac19c2e65cdad368668aff514f14/src/patches-custom-elements.js
|
||||||
|
if (window.ShadowDOMPolyfill) {
|
||||||
|
|
||||||
|
// ensure wrapped inputs for these functions
|
||||||
|
var fns = ['upgradeAll', 'upgradeSubtree', 'observeDocument',
|
||||||
|
'upgradeDocument'];
|
||||||
|
|
||||||
|
// cache originals
|
||||||
|
var original = {};
|
||||||
|
fns.forEach(function(fn) {
|
||||||
|
original[fn] = CustomElements[fn];
|
||||||
|
});
|
||||||
|
|
||||||
|
// override
|
||||||
|
fns.forEach(function(fn) {
|
||||||
|
CustomElements[fn] = function(inNode) {
|
||||||
|
return original[fn](window.ShadowDOMPolyfill.wrapIfNeeded(inNode));
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Patch to make importNode work.
|
||||||
|
// https://github.com/Polymer/platform-dev/blob/64a92f273462f04a84abbe2f054294f2b62dbcd6/src/patches-mdv.js
|
||||||
|
if (window.CustomElements && !CustomElements.useNative) {
|
||||||
|
var originalImportNode = Document.prototype.importNode;
|
||||||
|
Document.prototype.importNode = function(node, deep) {
|
||||||
|
var imported = originalImportNode.call(this, node, deep);
|
||||||
|
CustomElements.upgradeAll(imported);
|
||||||
|
return imported;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
28
runtime/bin/vmservice/observatory/deployed/web/packages/custom_element/custom-elements.min.js
vendored
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
var thisFile = 'html_import.debug.js';
|
||||||
|
var scopeName = 'HTMLImports';
|
||||||
|
var modules = [
|
||||||
|
'src/Parser.js',
|
||||||
|
'src/HTMLImports.js',
|
||||||
|
'src/boot.js'
|
||||||
|
];
|
||||||
|
|
||||||
|
// export
|
||||||
|
|
||||||
|
window[scopeName] = {
|
||||||
|
entryPointName: thisFile,
|
||||||
|
modules: modules
|
||||||
|
};
|
||||||
|
|
||||||
|
// bootstrap
|
||||||
|
|
||||||
|
var script = document.querySelector('script[src*="' + thisFile + '"]');
|
||||||
|
var src = script.attributes.src.value;
|
||||||
|
var basePath = src.slice(0, src.indexOf(thisFile));
|
||||||
|
|
||||||
|
if (!window.Loader) {
|
||||||
|
var path = basePath + 'tools/loader/loader.js';
|
||||||
|
document.write('<script src="' + path + '"></script>');
|
||||||
|
}
|
||||||
|
document.write('<script>Loader.load("' + scopeName + '")</script>');
|
||||||
|
|
||||||
|
})();
|
28
runtime/bin/vmservice/observatory/deployed/web/packages/html_import/html_import.min.js
vendored
Normal file
|
@ -0,0 +1,423 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function(scope) {
|
||||||
|
|
||||||
|
if (!scope) {
|
||||||
|
scope = window.HTMLImports = {flags:{}};
|
||||||
|
}
|
||||||
|
|
||||||
|
// imports
|
||||||
|
|
||||||
|
var xhr = scope.xhr;
|
||||||
|
|
||||||
|
// importer
|
||||||
|
|
||||||
|
var IMPORT_LINK_TYPE = 'import';
|
||||||
|
var STYLE_LINK_TYPE = 'stylesheet';
|
||||||
|
|
||||||
|
// highlander object represents a primary document (the argument to 'load')
|
||||||
|
// at the root of a tree of documents
|
||||||
|
|
||||||
|
// for any document, importer:
|
||||||
|
// - loads any linked documents (with deduping), modifies paths and feeds them back into importer
|
||||||
|
// - loads text of external script tags
|
||||||
|
// - loads text of external style tags inside of <element>, modifies paths
|
||||||
|
|
||||||
|
// when importer 'modifies paths' in a document, this includes
|
||||||
|
// - href/src/action in node attributes
|
||||||
|
// - paths in inline stylesheets
|
||||||
|
// - all content inside templates
|
||||||
|
|
||||||
|
// linked style sheets in an import have their own path fixed up when their containing import modifies paths
|
||||||
|
// linked style sheets in an <element> are loaded, and the content gets path fixups
|
||||||
|
// inline style sheets get path fixups when their containing import modifies paths
|
||||||
|
|
||||||
|
var loader;
|
||||||
|
|
||||||
|
var importer = {
|
||||||
|
documents: {},
|
||||||
|
cache: {},
|
||||||
|
preloadSelectors: [
|
||||||
|
'link[rel=' + IMPORT_LINK_TYPE + ']',
|
||||||
|
'element link[rel=' + STYLE_LINK_TYPE + ']',
|
||||||
|
'template',
|
||||||
|
'script[src]:not([type])',
|
||||||
|
'script[src][type="text/javascript"]'
|
||||||
|
].join(','),
|
||||||
|
loader: function(inNext) {
|
||||||
|
// construct a loader instance
|
||||||
|
loader = new Loader(importer.loaded, inNext);
|
||||||
|
// alias the loader cache (for debugging)
|
||||||
|
loader.cache = importer.cache;
|
||||||
|
return loader;
|
||||||
|
},
|
||||||
|
load: function(inDocument, inNext) {
|
||||||
|
// construct a loader instance
|
||||||
|
loader = importer.loader(inNext);
|
||||||
|
// add nodes from document into loader queue
|
||||||
|
importer.preload(inDocument);
|
||||||
|
},
|
||||||
|
preload: function(inDocument) {
|
||||||
|
// all preloadable nodes in inDocument
|
||||||
|
var nodes = inDocument.querySelectorAll(importer.preloadSelectors);
|
||||||
|
// from the main document, only load imports
|
||||||
|
// TODO(sjmiles): do this by altering the selector list instead
|
||||||
|
nodes = this.filterMainDocumentNodes(inDocument, nodes);
|
||||||
|
// extra link nodes from templates, filter templates out of the nodes list
|
||||||
|
nodes = this.extractTemplateNodes(nodes);
|
||||||
|
// add these nodes to loader's queue
|
||||||
|
loader.addNodes(nodes);
|
||||||
|
},
|
||||||
|
filterMainDocumentNodes: function(inDocument, nodes) {
|
||||||
|
if (inDocument === document) {
|
||||||
|
nodes = Array.prototype.filter.call(nodes, function(n) {
|
||||||
|
return !isScript(n);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return nodes;
|
||||||
|
},
|
||||||
|
extractTemplateNodes: function(nodes) {
|
||||||
|
var extra = [];
|
||||||
|
nodes = Array.prototype.filter.call(nodes, function(n) {
|
||||||
|
if (n.localName === 'template') {
|
||||||
|
if (n.content) {
|
||||||
|
var l$ = n.content.querySelectorAll('link[rel=' + STYLE_LINK_TYPE +
|
||||||
|
']');
|
||||||
|
if (l$.length) {
|
||||||
|
extra = extra.concat(Array.prototype.slice.call(l$, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
if (extra.length) {
|
||||||
|
nodes = nodes.concat(extra);
|
||||||
|
}
|
||||||
|
return nodes;
|
||||||
|
},
|
||||||
|
loaded: function(url, elt, resource) {
|
||||||
|
if (isDocumentLink(elt)) {
|
||||||
|
var document = importer.documents[url];
|
||||||
|
// if we've never seen a document at this url
|
||||||
|
if (!document) {
|
||||||
|
// generate an HTMLDocument from data
|
||||||
|
document = makeDocument(resource, url);
|
||||||
|
// resolve resource paths relative to host document
|
||||||
|
path.resolvePathsInHTML(document);
|
||||||
|
// cache document
|
||||||
|
importer.documents[url] = document;
|
||||||
|
// add nodes from this document to the loader queue
|
||||||
|
importer.preload(document);
|
||||||
|
}
|
||||||
|
// store import record
|
||||||
|
elt.import = {
|
||||||
|
href: url,
|
||||||
|
ownerNode: elt,
|
||||||
|
content: document
|
||||||
|
};
|
||||||
|
// store document resource
|
||||||
|
elt.content = resource = document;
|
||||||
|
}
|
||||||
|
// store generic resource
|
||||||
|
// TODO(sorvell): fails for nodes inside <template>.content
|
||||||
|
// see https://code.google.com/p/chromium/issues/detail?id=249381.
|
||||||
|
elt.__resource = resource;
|
||||||
|
// css path fixups
|
||||||
|
if (isStylesheetLink(elt)) {
|
||||||
|
path.resolvePathsInStylesheet(elt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function isDocumentLink(elt) {
|
||||||
|
return isLinkRel(elt, IMPORT_LINK_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isStylesheetLink(elt) {
|
||||||
|
return isLinkRel(elt, STYLE_LINK_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isLinkRel(elt, rel) {
|
||||||
|
return elt.localName === 'link' && elt.getAttribute('rel') === rel;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isScript(elt) {
|
||||||
|
return elt.localName === 'script';
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeDocument(resource, url) {
|
||||||
|
// create a new HTML document
|
||||||
|
var doc = resource;
|
||||||
|
if (!(doc instanceof Document)) {
|
||||||
|
doc = document.implementation.createHTMLDocument(IMPORT_LINK_TYPE);
|
||||||
|
// install html
|
||||||
|
doc.body.innerHTML = resource;
|
||||||
|
}
|
||||||
|
// cache the new document's source url
|
||||||
|
doc._URL = url;
|
||||||
|
// establish a relative path via <base>
|
||||||
|
var base = doc.createElement('base');
|
||||||
|
base.setAttribute('href', document.baseURI);
|
||||||
|
doc.head.appendChild(base);
|
||||||
|
// TODO(sorvell): MDV Polyfill intrusion: boostrap template polyfill
|
||||||
|
if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {
|
||||||
|
HTMLTemplateElement.bootstrap(doc);
|
||||||
|
}
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
var Loader = function(inOnLoad, inOnComplete) {
|
||||||
|
this.onload = inOnLoad;
|
||||||
|
this.oncomplete = inOnComplete;
|
||||||
|
this.inflight = 0;
|
||||||
|
this.pending = {};
|
||||||
|
this.cache = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
Loader.prototype = {
|
||||||
|
addNodes: function(inNodes) {
|
||||||
|
// number of transactions to complete
|
||||||
|
this.inflight += inNodes.length;
|
||||||
|
// commence transactions
|
||||||
|
forEach(inNodes, this.require, this);
|
||||||
|
// anything to do?
|
||||||
|
this.checkDone();
|
||||||
|
},
|
||||||
|
require: function(inElt) {
|
||||||
|
var url = path.nodeUrl(inElt);
|
||||||
|
// TODO(sjmiles): ad-hoc
|
||||||
|
inElt.__nodeUrl = url;
|
||||||
|
// deduplication
|
||||||
|
if (!this.dedupe(url, inElt)) {
|
||||||
|
// fetch this resource
|
||||||
|
this.fetch(url, inElt);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dedupe: function(inUrl, inElt) {
|
||||||
|
if (this.pending[inUrl]) {
|
||||||
|
// add to list of nodes waiting for inUrl
|
||||||
|
this.pending[inUrl].push(inElt);
|
||||||
|
// don't need fetch
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (this.cache[inUrl]) {
|
||||||
|
// complete load using cache data
|
||||||
|
this.onload(inUrl, inElt, loader.cache[inUrl]);
|
||||||
|
// finished this transaction
|
||||||
|
this.tail();
|
||||||
|
// don't need fetch
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// first node waiting for inUrl
|
||||||
|
this.pending[inUrl] = [inElt];
|
||||||
|
// need fetch (not a dupe)
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
fetch: function(url, elt) {
|
||||||
|
var receiveXhr = function(err, resource) {
|
||||||
|
this.receive(url, elt, err, resource);
|
||||||
|
}.bind(this);
|
||||||
|
xhr.load(url, receiveXhr);
|
||||||
|
// TODO(sorvell): blocked on
|
||||||
|
// https://code.google.com/p/chromium/issues/detail?id=257221
|
||||||
|
// xhr'ing for a document makes scripts in imports runnable; otherwise
|
||||||
|
// they are not; however, it requires that we have doctype=html in
|
||||||
|
// the import which is unacceptable. This is only needed on Chrome
|
||||||
|
// to avoid the bug above.
|
||||||
|
/*
|
||||||
|
if (isDocumentLink(elt)) {
|
||||||
|
xhr.loadDocument(url, receiveXhr);
|
||||||
|
} else {
|
||||||
|
xhr.load(url, receiveXhr);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
},
|
||||||
|
receive: function(inUrl, inElt, inErr, inResource) {
|
||||||
|
if (!inErr) {
|
||||||
|
loader.cache[inUrl] = inResource;
|
||||||
|
}
|
||||||
|
loader.pending[inUrl].forEach(function(e) {
|
||||||
|
if (!inErr) {
|
||||||
|
this.onload(inUrl, e, inResource);
|
||||||
|
}
|
||||||
|
this.tail();
|
||||||
|
}, this);
|
||||||
|
loader.pending[inUrl] = null;
|
||||||
|
},
|
||||||
|
tail: function() {
|
||||||
|
--this.inflight;
|
||||||
|
this.checkDone();
|
||||||
|
},
|
||||||
|
checkDone: function() {
|
||||||
|
if (!this.inflight) {
|
||||||
|
this.oncomplete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var URL_ATTRS = ['href', 'src', 'action'];
|
||||||
|
var URL_ATTRS_SELECTOR = '[' + URL_ATTRS.join('],[') + ']';
|
||||||
|
var URL_TEMPLATE_SEARCH = '{{.*}}';
|
||||||
|
|
||||||
|
var path = {
|
||||||
|
nodeUrl: function(inNode) {
|
||||||
|
return path.resolveUrl(path.getDocumentUrl(document), path.hrefOrSrc(inNode));
|
||||||
|
},
|
||||||
|
hrefOrSrc: function(inNode) {
|
||||||
|
return inNode.getAttribute("href") || inNode.getAttribute("src");
|
||||||
|
},
|
||||||
|
documentUrlFromNode: function(inNode) {
|
||||||
|
return path.getDocumentUrl(inNode.ownerDocument || inNode);
|
||||||
|
},
|
||||||
|
getDocumentUrl: function(inDocument) {
|
||||||
|
var url = inDocument &&
|
||||||
|
// TODO(sjmiles): ShadowDOMPolyfill intrusion
|
||||||
|
(inDocument._URL || (inDocument.impl && inDocument.impl._URL)
|
||||||
|
|| inDocument.baseURI || inDocument.URL)
|
||||||
|
|| '';
|
||||||
|
// take only the left side if there is a #
|
||||||
|
return url.split('#')[0];
|
||||||
|
},
|
||||||
|
resolveUrl: function(inBaseUrl, inUrl, inRelativeToDocument) {
|
||||||
|
if (this.isAbsUrl(inUrl)) {
|
||||||
|
return inUrl;
|
||||||
|
}
|
||||||
|
var url = this.compressUrl(this.urlToPath(inBaseUrl) + inUrl);
|
||||||
|
if (inRelativeToDocument) {
|
||||||
|
url = path.makeRelPath(path.getDocumentUrl(document), url);
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
},
|
||||||
|
isAbsUrl: function(inUrl) {
|
||||||
|
return /(^data:)|(^http[s]?:)|(^\/)/.test(inUrl);
|
||||||
|
},
|
||||||
|
urlToPath: function(inBaseUrl) {
|
||||||
|
var parts = inBaseUrl.split("/");
|
||||||
|
parts.pop();
|
||||||
|
parts.push('');
|
||||||
|
return parts.join("/");
|
||||||
|
},
|
||||||
|
compressUrl: function(inUrl) {
|
||||||
|
var parts = inUrl.split("/");
|
||||||
|
for (var i=0, p; i<parts.length; i++) {
|
||||||
|
p = parts[i];
|
||||||
|
if (p === "..") {
|
||||||
|
parts.splice(i-1, 2);
|
||||||
|
i -= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parts.join("/");
|
||||||
|
},
|
||||||
|
// make a relative path from source to target
|
||||||
|
makeRelPath: function(inSource, inTarget) {
|
||||||
|
var s, t;
|
||||||
|
s = this.compressUrl(inSource).split("/");
|
||||||
|
t = this.compressUrl(inTarget).split("/");
|
||||||
|
while (s.length && s[0] === t[0]){
|
||||||
|
s.shift();
|
||||||
|
t.shift();
|
||||||
|
}
|
||||||
|
for(var i = 0, l = s.length-1; i < l; i++) {
|
||||||
|
t.unshift("..");
|
||||||
|
}
|
||||||
|
var r = t.join("/");
|
||||||
|
return r;
|
||||||
|
},
|
||||||
|
resolvePathsInHTML: function(root, url) {
|
||||||
|
url = url || path.documentUrlFromNode(root)
|
||||||
|
path.resolveAttributes(root, url);
|
||||||
|
path.resolveStyleElts(root, url);
|
||||||
|
// handle template.content
|
||||||
|
var templates = root.querySelectorAll('template');
|
||||||
|
if (templates) {
|
||||||
|
forEach(templates, function(t) {
|
||||||
|
if (t.content) {
|
||||||
|
path.resolvePathsInHTML(t.content, url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resolvePathsInStylesheet: function(inSheet) {
|
||||||
|
var docUrl = path.nodeUrl(inSheet);
|
||||||
|
inSheet.__resource = path.resolveCssText(inSheet.__resource, docUrl);
|
||||||
|
},
|
||||||
|
resolveStyleElts: function(inRoot, inUrl) {
|
||||||
|
var styles = inRoot.querySelectorAll('style');
|
||||||
|
if (styles) {
|
||||||
|
forEach(styles, function(style) {
|
||||||
|
style.textContent = path.resolveCssText(style.textContent, inUrl);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resolveCssText: function(inCssText, inBaseUrl) {
|
||||||
|
return inCssText.replace(/url\([^)]*\)/g, function(inMatch) {
|
||||||
|
// find the url path, ignore quotes in url string
|
||||||
|
var urlPath = inMatch.replace(/["']/g, "").slice(4, -1);
|
||||||
|
urlPath = path.resolveUrl(inBaseUrl, urlPath, true);
|
||||||
|
return "url(" + urlPath + ")";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
resolveAttributes: function(inRoot, inUrl) {
|
||||||
|
// search for attributes that host urls
|
||||||
|
var nodes = inRoot && inRoot.querySelectorAll(URL_ATTRS_SELECTOR);
|
||||||
|
if (nodes) {
|
||||||
|
forEach(nodes, function(n) {
|
||||||
|
this.resolveNodeAttributes(n, inUrl);
|
||||||
|
}, this);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resolveNodeAttributes: function(inNode, inUrl) {
|
||||||
|
URL_ATTRS.forEach(function(v) {
|
||||||
|
var attr = inNode.attributes[v];
|
||||||
|
if (attr && attr.value &&
|
||||||
|
(attr.value.search(URL_TEMPLATE_SEARCH) < 0)) {
|
||||||
|
var urlPath = path.resolveUrl(inUrl, attr.value, true);
|
||||||
|
attr.value = urlPath;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
xhr = xhr || {
|
||||||
|
async: true,
|
||||||
|
ok: function(inRequest) {
|
||||||
|
return (inRequest.status >= 200 && inRequest.status < 300)
|
||||||
|
|| (inRequest.status === 304)
|
||||||
|
|| (inRequest.status === 0);
|
||||||
|
},
|
||||||
|
load: function(url, next, nextContext) {
|
||||||
|
var request = new XMLHttpRequest();
|
||||||
|
if (scope.flags.debug || scope.flags.bust) {
|
||||||
|
url += '?' + Math.random();
|
||||||
|
}
|
||||||
|
request.open('GET', url, xhr.async);
|
||||||
|
request.addEventListener('readystatechange', function(e) {
|
||||||
|
if (request.readyState === 4) {
|
||||||
|
next.call(nextContext, !xhr.ok(request) && request,
|
||||||
|
request.response, url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
request.send();
|
||||||
|
return request;
|
||||||
|
},
|
||||||
|
loadDocument: function(url, next, nextContext) {
|
||||||
|
this.load(url, next, nextContext).responseType = 'document';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
|
||||||
|
|
||||||
|
// exports
|
||||||
|
|
||||||
|
scope.path = path;
|
||||||
|
scope.xhr = xhr;
|
||||||
|
scope.importer = importer;
|
||||||
|
scope.getDocumentUrl = path.getDocumentUrl;
|
||||||
|
scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
|
||||||
|
|
||||||
|
})(window.HTMLImports);
|
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function(scope) {
|
||||||
|
|
||||||
|
var IMPORT_LINK_TYPE = 'import';
|
||||||
|
|
||||||
|
// highlander object for parsing a document tree
|
||||||
|
|
||||||
|
var importParser = {
|
||||||
|
selectors: [
|
||||||
|
'link[rel=' + IMPORT_LINK_TYPE + ']',
|
||||||
|
'link[rel=stylesheet]',
|
||||||
|
'style',
|
||||||
|
'script:not([type])',
|
||||||
|
'script[type="text/javascript"]'
|
||||||
|
],
|
||||||
|
map: {
|
||||||
|
link: 'parseLink',
|
||||||
|
script: 'parseScript',
|
||||||
|
style: 'parseGeneric'
|
||||||
|
},
|
||||||
|
parse: function(inDocument) {
|
||||||
|
if (!inDocument.__importParsed) {
|
||||||
|
// only parse once
|
||||||
|
inDocument.__importParsed = true;
|
||||||
|
// all parsable elements in inDocument (depth-first pre-order traversal)
|
||||||
|
var elts = inDocument.querySelectorAll(importParser.selectors);
|
||||||
|
// for each parsable node type, call the mapped parsing method
|
||||||
|
forEach(elts, function(e) {
|
||||||
|
importParser[importParser.map[e.localName]](e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
parseLink: function(linkElt) {
|
||||||
|
if (isDocumentLink(linkElt)) {
|
||||||
|
if (linkElt.content) {
|
||||||
|
importParser.parse(linkElt.content);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.parseGeneric(linkElt);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
parseGeneric: function(elt) {
|
||||||
|
if (needsMainDocumentContext(elt)) {
|
||||||
|
document.head.appendChild(elt);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
parseScript: function(scriptElt) {
|
||||||
|
if (needsMainDocumentContext(scriptElt)) {
|
||||||
|
// acquire code to execute
|
||||||
|
var code = (scriptElt.__resource || scriptElt.textContent).trim();
|
||||||
|
if (code) {
|
||||||
|
// calculate source map hint
|
||||||
|
var moniker = scriptElt.__nodeUrl;
|
||||||
|
if (!moniker) {
|
||||||
|
var moniker = scope.path.documentUrlFromNode(scriptElt);
|
||||||
|
// there could be more than one script this url
|
||||||
|
var tag = '[' + Math.floor((Math.random()+1)*1000) + ']';
|
||||||
|
// TODO(sjmiles): Polymer hack, should be pluggable if we need to allow
|
||||||
|
// this sort of thing
|
||||||
|
var matches = code.match(/Polymer\(['"]([^'"]*)/);
|
||||||
|
tag = matches && matches[1] || tag;
|
||||||
|
// tag the moniker
|
||||||
|
moniker += '/' + tag + '.js';
|
||||||
|
}
|
||||||
|
// source map hint
|
||||||
|
code += "\n//# sourceURL=" + moniker + "\n";
|
||||||
|
// evaluate the code
|
||||||
|
eval.call(window, code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
|
||||||
|
|
||||||
|
function isDocumentLink(elt) {
|
||||||
|
return elt.localName === 'link'
|
||||||
|
&& elt.getAttribute('rel') === IMPORT_LINK_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
function needsMainDocumentContext(node) {
|
||||||
|
// nodes can be moved to the main document:
|
||||||
|
// if they are in a tree but not in the main document and not children of <element>
|
||||||
|
return node.parentNode && !inMainDocument(node)
|
||||||
|
&& !isElementElementChild(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
function inMainDocument(elt) {
|
||||||
|
return elt.ownerDocument === document ||
|
||||||
|
// TODO(sjmiles): ShadowDOMPolyfill intrusion
|
||||||
|
elt.ownerDocument.impl === document;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isElementElementChild(elt) {
|
||||||
|
return elt.parentNode && elt.parentNode.localName === 'element';
|
||||||
|
}
|
||||||
|
|
||||||
|
// exports
|
||||||
|
|
||||||
|
scope.parser = importParser;
|
||||||
|
|
||||||
|
})(HTMLImports);
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
// bootstrap
|
||||||
|
|
||||||
|
// IE shim for CustomEvent
|
||||||
|
if (typeof window.CustomEvent !== 'function') {
|
||||||
|
window.CustomEvent = function(inType) {
|
||||||
|
var e = document.createEvent('HTMLEvents');
|
||||||
|
e.initEvent(inType, true, true);
|
||||||
|
return e;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function bootstrap() {
|
||||||
|
// preload document resource trees
|
||||||
|
HTMLImports.importer.load(document, function() {
|
||||||
|
HTMLImports.parser.parse(document);
|
||||||
|
HTMLImports.readyTime = new Date().getTime();
|
||||||
|
// send HTMLImportsLoaded when finished
|
||||||
|
document.dispatchEvent(
|
||||||
|
new CustomEvent('HTMLImportsLoaded', {bubbles: true})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (document.readyState === 'complete') {
|
||||||
|
bootstrap();
|
||||||
|
} else {
|
||||||
|
window.addEventListener('DOMContentLoaded', bootstrap);
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
var scope = window.Loader = {};
|
||||||
|
var flags = {};
|
||||||
|
|
||||||
|
// convert url arguments to flags
|
||||||
|
|
||||||
|
if (!flags.noOpts) {
|
||||||
|
location.search.slice(1).split('&').forEach(function(o) {
|
||||||
|
o = o.split('=');
|
||||||
|
o[0] && (flags[o[0]] = o[1] || true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// process global logFlags
|
||||||
|
|
||||||
|
parseLogFlags(flags);
|
||||||
|
|
||||||
|
function load(scopeName) {
|
||||||
|
// imports
|
||||||
|
|
||||||
|
var scope = window[scopeName];
|
||||||
|
var entryPointName = scope.entryPointName;
|
||||||
|
var processFlags = scope.processFlags;
|
||||||
|
|
||||||
|
// acquire attributes and base path from entry point
|
||||||
|
|
||||||
|
var entryPoint = findScript(entryPointName);
|
||||||
|
var base = entryPoint.basePath;
|
||||||
|
|
||||||
|
// acquire common flags
|
||||||
|
var flags = Loader.flags;
|
||||||
|
|
||||||
|
// convert attributes to flags
|
||||||
|
var flags = Loader.flags;
|
||||||
|
for (var i=0, a; (a=entryPoint.attributes[i]); i++) {
|
||||||
|
if (a.name !== 'src') {
|
||||||
|
flags[a.name] = a.value || true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse log flags into global
|
||||||
|
parseLogFlags(flags);
|
||||||
|
|
||||||
|
// exports
|
||||||
|
|
||||||
|
scope.basePath = base;
|
||||||
|
scope.flags = flags;
|
||||||
|
|
||||||
|
// process flags for dynamic dependencies
|
||||||
|
|
||||||
|
if (processFlags) {
|
||||||
|
processFlags.call(scope, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
// post-process imports
|
||||||
|
|
||||||
|
var modules = scope.modules || [];
|
||||||
|
var sheets = scope.sheets || [];
|
||||||
|
|
||||||
|
// write script tags for dependencies
|
||||||
|
|
||||||
|
modules.forEach(function(src) {
|
||||||
|
document.write('<script src="' + base + src + '"></script>');
|
||||||
|
});
|
||||||
|
|
||||||
|
// write link tags for styles
|
||||||
|
|
||||||
|
sheets.forEach(function(src) {
|
||||||
|
document.write('<link rel="stylesheet" href="' + base + src + '">');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// utility method
|
||||||
|
|
||||||
|
function findScript(fileName) {
|
||||||
|
var script = document.querySelector('script[src*="' + fileName + '"]');
|
||||||
|
var src = script.attributes.src.value;
|
||||||
|
script.basePath = src.slice(0, src.indexOf(fileName));
|
||||||
|
return script;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseLogFlags(flags) {
|
||||||
|
var logFlags = window.logFlags = window.logFlags || {};
|
||||||
|
if (flags.log) {
|
||||||
|
flags.log.split(',').forEach(function(f) {
|
||||||
|
logFlags[f] = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.flags = flags;
|
||||||
|
scope.load = load;
|
||||||
|
|
||||||
|
})();
|
|
@ -0,0 +1,588 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 The Polymer Authors. All rights reserved.
|
||||||
|
* Use of this source code is goverened by a BSD-style
|
||||||
|
* license that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TODO(jmesserly): polyfill does not have feature testing or the definition of
|
||||||
|
// SideTable. The extra code is from:
|
||||||
|
// https://github.com/Polymer/CustomElements/blob/master/src/MutationObserver.js
|
||||||
|
// https://github.com/Polymer/CustomElements/blob/master/src/sidetable.js
|
||||||
|
// I also renamed JsMutationObserver -> MutationObserver to correctly interact
|
||||||
|
// with dart2js interceptors.
|
||||||
|
|
||||||
|
if (!window.MutationObserver && !window.WebKitMutationObserver) {
|
||||||
|
|
||||||
|
(function(global) {
|
||||||
|
// SideTable is a weak map where possible. If WeakMap is not available the
|
||||||
|
// association is stored as an expando property.
|
||||||
|
var SideTable;
|
||||||
|
// TODO(arv): WeakMap does not allow for Node etc to be keys in Firefox
|
||||||
|
if (typeof WeakMap !== 'undefined' && navigator.userAgent.indexOf('Firefox/') < 0) {
|
||||||
|
SideTable = WeakMap;
|
||||||
|
} else {
|
||||||
|
(function() {
|
||||||
|
var defineProperty = Object.defineProperty;
|
||||||
|
var hasOwnProperty = Object.hasOwnProperty;
|
||||||
|
var counter = new Date().getTime() % 1e9;
|
||||||
|
|
||||||
|
SideTable = function() {
|
||||||
|
this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__');
|
||||||
|
};
|
||||||
|
|
||||||
|
SideTable.prototype = {
|
||||||
|
set: function(key, value) {
|
||||||
|
defineProperty(key, this.name, {value: value, writable: true});
|
||||||
|
},
|
||||||
|
get: function(key) {
|
||||||
|
return hasOwnProperty.call(key, this.name) ? key[this.name] : undefined;
|
||||||
|
},
|
||||||
|
delete: function(key) {
|
||||||
|
this.set(key, undefined);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
var registrationsTable = new SideTable();
|
||||||
|
|
||||||
|
// We use setImmediate or postMessage for our future callback.
|
||||||
|
var setImmediate = window.msSetImmediate;
|
||||||
|
|
||||||
|
// Use post message to emulate setImmediate.
|
||||||
|
if (!setImmediate) {
|
||||||
|
var setImmediateQueue = [];
|
||||||
|
var sentinel = String(Math.random());
|
||||||
|
window.addEventListener('message', function(e) {
|
||||||
|
if (e.data === sentinel) {
|
||||||
|
var queue = setImmediateQueue;
|
||||||
|
setImmediateQueue = [];
|
||||||
|
queue.forEach(function(func) {
|
||||||
|
func();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setImmediate = function(func) {
|
||||||
|
setImmediateQueue.push(func);
|
||||||
|
window.postMessage(sentinel, '*');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is used to ensure that we never schedule 2 callas to setImmediate
|
||||||
|
var isScheduled = false;
|
||||||
|
|
||||||
|
// Keep track of observers that needs to be notified next time.
|
||||||
|
var scheduledObservers = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules |dispatchCallback| to be called in the future.
|
||||||
|
* @param {MutationObserver} observer
|
||||||
|
*/
|
||||||
|
function scheduleCallback(observer) {
|
||||||
|
scheduledObservers.push(observer);
|
||||||
|
if (!isScheduled) {
|
||||||
|
isScheduled = true;
|
||||||
|
setImmediate(dispatchCallbacks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function wrapIfNeeded(node) {
|
||||||
|
return window.ShadowDOMPolyfill &&
|
||||||
|
window.ShadowDOMPolyfill.wrapIfNeeded(node) ||
|
||||||
|
node;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatchCallbacks() {
|
||||||
|
// http://dom.spec.whatwg.org/#mutation-observers
|
||||||
|
|
||||||
|
isScheduled = false; // Used to allow a new setImmediate call above.
|
||||||
|
|
||||||
|
var observers = scheduledObservers;
|
||||||
|
scheduledObservers = [];
|
||||||
|
// Sort observers based on their creation UID (incremental).
|
||||||
|
observers.sort(function(o1, o2) {
|
||||||
|
return o1.uid_ - o2.uid_;
|
||||||
|
});
|
||||||
|
|
||||||
|
var anyNonEmpty = false;
|
||||||
|
observers.forEach(function(observer) {
|
||||||
|
|
||||||
|
// 2.1, 2.2
|
||||||
|
var queue = observer.takeRecords();
|
||||||
|
// 2.3. Remove all transient registered observers whose observer is mo.
|
||||||
|
removeTransientObserversFor(observer);
|
||||||
|
|
||||||
|
// 2.4
|
||||||
|
if (queue.length) {
|
||||||
|
observer.callback_(queue, observer);
|
||||||
|
anyNonEmpty = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3.
|
||||||
|
if (anyNonEmpty)
|
||||||
|
dispatchCallbacks();
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeTransientObserversFor(observer) {
|
||||||
|
observer.nodes_.forEach(function(node) {
|
||||||
|
var registrations = registrationsTable.get(node);
|
||||||
|
if (!registrations)
|
||||||
|
return;
|
||||||
|
registrations.forEach(function(registration) {
|
||||||
|
if (registration.observer === observer)
|
||||||
|
registration.removeTransientObservers();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is used for the "For each registered observer observer (with
|
||||||
|
* observer's options as options) in target's list of registered observers,
|
||||||
|
* run these substeps:" and the "For each ancestor ancestor of target, and for
|
||||||
|
* each registered observer observer (with options options) in ancestor's list
|
||||||
|
* of registered observers, run these substeps:" part of the algorithms. The
|
||||||
|
* |options.subtree| is checked to ensure that the callback is called
|
||||||
|
* correctly.
|
||||||
|
*
|
||||||
|
* @param {Node} target
|
||||||
|
* @param {function(MutationObserverInit):MutationRecord} callback
|
||||||
|
*/
|
||||||
|
function forEachAncestorAndObserverEnqueueRecord(target, callback) {
|
||||||
|
for (var node = target; node; node = node.parentNode) {
|
||||||
|
var registrations = registrationsTable.get(node);
|
||||||
|
|
||||||
|
if (registrations) {
|
||||||
|
for (var j = 0; j < registrations.length; j++) {
|
||||||
|
var registration = registrations[j];
|
||||||
|
var options = registration.options;
|
||||||
|
|
||||||
|
// Only target ignores subtree.
|
||||||
|
if (node !== target && !options.subtree)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var record = callback(options);
|
||||||
|
if (record)
|
||||||
|
registration.enqueue(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var uidCounter = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class that maps to the DOM MutationObserver interface.
|
||||||
|
* @param {Function} callback.
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function MutationObserver(callback) {
|
||||||
|
this.callback_ = callback;
|
||||||
|
this.nodes_ = [];
|
||||||
|
this.records_ = [];
|
||||||
|
this.uid_ = ++uidCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
MutationObserver.prototype = {
|
||||||
|
observe: function(target, options) {
|
||||||
|
target = wrapIfNeeded(target);
|
||||||
|
|
||||||
|
// 1.1
|
||||||
|
if (!options.childList && !options.attributes && !options.characterData ||
|
||||||
|
|
||||||
|
// 1.2
|
||||||
|
options.attributeOldValue && !options.attributes ||
|
||||||
|
|
||||||
|
// 1.3
|
||||||
|
options.attributeFilter && options.attributeFilter.length &&
|
||||||
|
!options.attributes ||
|
||||||
|
|
||||||
|
// 1.4
|
||||||
|
options.characterDataOldValue && !options.characterData) {
|
||||||
|
|
||||||
|
throw new SyntaxError();
|
||||||
|
}
|
||||||
|
|
||||||
|
var registrations = registrationsTable.get(target);
|
||||||
|
if (!registrations)
|
||||||
|
registrationsTable.set(target, registrations = []);
|
||||||
|
|
||||||
|
// 2
|
||||||
|
// If target's list of registered observers already includes a registered
|
||||||
|
// observer associated with the context object, replace that registered
|
||||||
|
// observer's options with options.
|
||||||
|
var registration;
|
||||||
|
for (var i = 0; i < registrations.length; i++) {
|
||||||
|
if (registrations[i].observer === this) {
|
||||||
|
registration = registrations[i];
|
||||||
|
registration.removeListeners();
|
||||||
|
registration.options = options;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3.
|
||||||
|
// Otherwise, add a new registered observer to target's list of registered
|
||||||
|
// observers with the context object as the observer and options as the
|
||||||
|
// options, and add target to context object's list of nodes on which it
|
||||||
|
// is registered.
|
||||||
|
if (!registration) {
|
||||||
|
registration = new Registration(this, target, options);
|
||||||
|
registrations.push(registration);
|
||||||
|
this.nodes_.push(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
registration.addListeners();
|
||||||
|
},
|
||||||
|
|
||||||
|
disconnect: function() {
|
||||||
|
this.nodes_.forEach(function(node) {
|
||||||
|
var registrations = registrationsTable.get(node);
|
||||||
|
for (var i = 0; i < registrations.length; i++) {
|
||||||
|
var registration = registrations[i];
|
||||||
|
if (registration.observer === this) {
|
||||||
|
registration.removeListeners();
|
||||||
|
registrations.splice(i, 1);
|
||||||
|
// Each node can only have one registered observer associated with
|
||||||
|
// this observer.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
this.records_ = [];
|
||||||
|
},
|
||||||
|
|
||||||
|
takeRecords: function() {
|
||||||
|
var copyOfRecords = this.records_;
|
||||||
|
this.records_ = [];
|
||||||
|
return copyOfRecords;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} type
|
||||||
|
* @param {Node} target
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function MutationRecord(type, target) {
|
||||||
|
this.type = type;
|
||||||
|
this.target = target;
|
||||||
|
this.addedNodes = [];
|
||||||
|
this.removedNodes = [];
|
||||||
|
this.previousSibling = null;
|
||||||
|
this.nextSibling = null;
|
||||||
|
this.attributeName = null;
|
||||||
|
this.attributeNamespace = null;
|
||||||
|
this.oldValue = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(jmesserly): this fixes the interceptor dispatch on IE.
|
||||||
|
// Not sure why this is necessary.
|
||||||
|
MutationObserver.prototype.constructor = MutationObserver;
|
||||||
|
MutationObserver.name = 'MutationObserver';
|
||||||
|
MutationRecord.prototype.constructor = MutationRecord;
|
||||||
|
MutationRecord.name = 'MutationRecord';
|
||||||
|
|
||||||
|
function copyMutationRecord(original) {
|
||||||
|
var record = new MutationRecord(original.type, original.target);
|
||||||
|
record.addedNodes = original.addedNodes.slice();
|
||||||
|
record.removedNodes = original.removedNodes.slice();
|
||||||
|
record.previousSibling = original.previousSibling;
|
||||||
|
record.nextSibling = original.nextSibling;
|
||||||
|
record.attributeName = original.attributeName;
|
||||||
|
record.attributeNamespace = original.attributeNamespace;
|
||||||
|
record.oldValue = original.oldValue;
|
||||||
|
return record;
|
||||||
|
};
|
||||||
|
|
||||||
|
// We keep track of the two (possibly one) records used in a single mutation.
|
||||||
|
var currentRecord, recordWithOldValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a record without |oldValue| and caches it as |currentRecord| for
|
||||||
|
* later use.
|
||||||
|
* @param {string} oldValue
|
||||||
|
* @return {MutationRecord}
|
||||||
|
*/
|
||||||
|
function getRecord(type, target) {
|
||||||
|
return currentRecord = new MutationRecord(type, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets or creates a record with |oldValue| based in the |currentRecord|
|
||||||
|
* @param {string} oldValue
|
||||||
|
* @return {MutationRecord}
|
||||||
|
*/
|
||||||
|
function getRecordWithOldValue(oldValue) {
|
||||||
|
if (recordWithOldValue)
|
||||||
|
return recordWithOldValue;
|
||||||
|
recordWithOldValue = copyMutationRecord(currentRecord);
|
||||||
|
recordWithOldValue.oldValue = oldValue;
|
||||||
|
return recordWithOldValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearRecords() {
|
||||||
|
currentRecord = recordWithOldValue = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {MutationRecord} record
|
||||||
|
* @return {boolean} Whether the record represents a record from the current
|
||||||
|
* mutation event.
|
||||||
|
*/
|
||||||
|
function recordRepresentsCurrentMutation(record) {
|
||||||
|
return record === recordWithOldValue || record === currentRecord;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selects which record, if any, to replace the last record in the queue.
|
||||||
|
* This returns |null| if no record should be replaced.
|
||||||
|
*
|
||||||
|
* @param {MutationRecord} lastRecord
|
||||||
|
* @param {MutationRecord} newRecord
|
||||||
|
* @param {MutationRecord}
|
||||||
|
*/
|
||||||
|
function selectRecord(lastRecord, newRecord) {
|
||||||
|
if (lastRecord === newRecord)
|
||||||
|
return lastRecord;
|
||||||
|
|
||||||
|
// Check if the the record we are adding represents the same record. If
|
||||||
|
// so, we keep the one with the oldValue in it.
|
||||||
|
if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord))
|
||||||
|
return recordWithOldValue;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class used to represent a registered observer.
|
||||||
|
* @param {MutationObserver} observer
|
||||||
|
* @param {Node} target
|
||||||
|
* @param {MutationObserverInit} options
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function Registration(observer, target, options) {
|
||||||
|
this.observer = observer;
|
||||||
|
this.target = target;
|
||||||
|
this.options = options;
|
||||||
|
this.transientObservedNodes = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
Registration.prototype = {
|
||||||
|
enqueue: function(record) {
|
||||||
|
var records = this.observer.records_;
|
||||||
|
var length = records.length;
|
||||||
|
|
||||||
|
// There are cases where we replace the last record with the new record.
|
||||||
|
// For example if the record represents the same mutation we need to use
|
||||||
|
// the one with the oldValue. If we get same record (this can happen as we
|
||||||
|
// walk up the tree) we ignore the new record.
|
||||||
|
if (records.length > 0) {
|
||||||
|
var lastRecord = records[length - 1];
|
||||||
|
var recordToReplaceLast = selectRecord(lastRecord, record);
|
||||||
|
if (recordToReplaceLast) {
|
||||||
|
records[length - 1] = recordToReplaceLast;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
scheduleCallback(this.observer);
|
||||||
|
}
|
||||||
|
|
||||||
|
records[length] = record;
|
||||||
|
},
|
||||||
|
|
||||||
|
addListeners: function() {
|
||||||
|
this.addListeners_(this.target);
|
||||||
|
},
|
||||||
|
|
||||||
|
addListeners_: function(node) {
|
||||||
|
var options = this.options;
|
||||||
|
if (options.attributes)
|
||||||
|
node.addEventListener('DOMAttrModified', this, true);
|
||||||
|
|
||||||
|
if (options.characterData)
|
||||||
|
node.addEventListener('DOMCharacterDataModified', this, true);
|
||||||
|
|
||||||
|
if (options.childList)
|
||||||
|
node.addEventListener('DOMNodeInserted', this, true);
|
||||||
|
|
||||||
|
if (options.childList || options.subtree)
|
||||||
|
node.addEventListener('DOMNodeRemoved', this, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
removeListeners: function() {
|
||||||
|
this.removeListeners_(this.target);
|
||||||
|
},
|
||||||
|
|
||||||
|
removeListeners_: function(node) {
|
||||||
|
var options = this.options;
|
||||||
|
if (options.attributes)
|
||||||
|
node.removeEventListener('DOMAttrModified', this, true);
|
||||||
|
|
||||||
|
if (options.characterData)
|
||||||
|
node.removeEventListener('DOMCharacterDataModified', this, true);
|
||||||
|
|
||||||
|
if (options.childList)
|
||||||
|
node.removeEventListener('DOMNodeInserted', this, true);
|
||||||
|
|
||||||
|
if (options.childList || options.subtree)
|
||||||
|
node.removeEventListener('DOMNodeRemoved', this, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a transient observer on node. The transient observer gets removed
|
||||||
|
* next time we deliver the change records.
|
||||||
|
* @param {Node} node
|
||||||
|
*/
|
||||||
|
addTransientObserver: function(node) {
|
||||||
|
// Don't add transient observers on the target itself. We already have all
|
||||||
|
// the required listeners set up on the target.
|
||||||
|
if (node === this.target)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.addListeners_(node);
|
||||||
|
this.transientObservedNodes.push(node);
|
||||||
|
var registrations = registrationsTable.get(node);
|
||||||
|
if (!registrations)
|
||||||
|
registrationsTable.set(node, registrations = []);
|
||||||
|
|
||||||
|
// We know that registrations does not contain this because we already
|
||||||
|
// checked if node === this.target.
|
||||||
|
registrations.push(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
removeTransientObservers: function() {
|
||||||
|
var transientObservedNodes = this.transientObservedNodes;
|
||||||
|
this.transientObservedNodes = [];
|
||||||
|
|
||||||
|
transientObservedNodes.forEach(function(node) {
|
||||||
|
// Transient observers are never added to the target.
|
||||||
|
this.removeListeners_(node);
|
||||||
|
|
||||||
|
var registrations = registrationsTable.get(node);
|
||||||
|
for (var i = 0; i < registrations.length; i++) {
|
||||||
|
if (registrations[i] === this) {
|
||||||
|
registrations.splice(i, 1);
|
||||||
|
// Each node can only have one registered observer associated with
|
||||||
|
// this observer.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
handleEvent: function(e) {
|
||||||
|
// Stop propagation since we are managing the propagation manually.
|
||||||
|
// This means that other mutation events on the page will not work
|
||||||
|
// correctly but that is by design.
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
|
||||||
|
switch (e.type) {
|
||||||
|
case 'DOMAttrModified':
|
||||||
|
// http://dom.spec.whatwg.org/#concept-mo-queue-attributes
|
||||||
|
|
||||||
|
var name = e.attrName;
|
||||||
|
var namespace = e.relatedNode.namespaceURI;
|
||||||
|
var target = e.target;
|
||||||
|
|
||||||
|
// 1.
|
||||||
|
var record = new getRecord('attributes', target);
|
||||||
|
record.attributeName = name;
|
||||||
|
record.attributeNamespace = namespace;
|
||||||
|
|
||||||
|
// 2.
|
||||||
|
var oldValue =
|
||||||
|
e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;
|
||||||
|
|
||||||
|
forEachAncestorAndObserverEnqueueRecord(target, function(options) {
|
||||||
|
// 3.1, 4.2
|
||||||
|
if (!options.attributes)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 3.2, 4.3
|
||||||
|
if (options.attributeFilter && options.attributeFilter.length &&
|
||||||
|
options.attributeFilter.indexOf(name) === -1 &&
|
||||||
|
options.attributeFilter.indexOf(namespace) === -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 3.3, 4.4
|
||||||
|
if (options.attributeOldValue)
|
||||||
|
return getRecordWithOldValue(oldValue);
|
||||||
|
|
||||||
|
// 3.4, 4.5
|
||||||
|
return record;
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'DOMCharacterDataModified':
|
||||||
|
// http://dom.spec.whatwg.org/#concept-mo-queue-characterdata
|
||||||
|
var target = e.target;
|
||||||
|
|
||||||
|
// 1.
|
||||||
|
var record = getRecord('characterData', target);
|
||||||
|
|
||||||
|
// 2.
|
||||||
|
var oldValue = e.prevValue;
|
||||||
|
|
||||||
|
|
||||||
|
forEachAncestorAndObserverEnqueueRecord(target, function(options) {
|
||||||
|
// 3.1, 4.2
|
||||||
|
if (!options.characterData)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 3.2, 4.3
|
||||||
|
if (options.characterDataOldValue)
|
||||||
|
return getRecordWithOldValue(oldValue);
|
||||||
|
|
||||||
|
// 3.3, 4.4
|
||||||
|
return record;
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'DOMNodeRemoved':
|
||||||
|
this.addTransientObserver(e.target);
|
||||||
|
// Fall through.
|
||||||
|
case 'DOMNodeInserted':
|
||||||
|
// http://dom.spec.whatwg.org/#concept-mo-queue-childlist
|
||||||
|
var target = e.relatedNode;
|
||||||
|
var changedNode = e.target;
|
||||||
|
var addedNodes, removedNodes;
|
||||||
|
if (e.type === 'DOMNodeInserted') {
|
||||||
|
addedNodes = [changedNode];
|
||||||
|
removedNodes = [];
|
||||||
|
} else {
|
||||||
|
|
||||||
|
addedNodes = [];
|
||||||
|
removedNodes = [changedNode];
|
||||||
|
}
|
||||||
|
var previousSibling = changedNode.previousSibling;
|
||||||
|
var nextSibling = changedNode.nextSibling;
|
||||||
|
|
||||||
|
// 1.
|
||||||
|
var record = getRecord('childList', target);
|
||||||
|
record.addedNodes = addedNodes;
|
||||||
|
record.removedNodes = removedNodes;
|
||||||
|
record.previousSibling = previousSibling;
|
||||||
|
record.nextSibling = nextSibling;
|
||||||
|
|
||||||
|
forEachAncestorAndObserverEnqueueRecord(target, function(options) {
|
||||||
|
// 2.1, 3.2
|
||||||
|
if (!options.childList)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 2.2, 3.3
|
||||||
|
return record;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
clearRecords();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
global.MutationObserver = MutationObserver;
|
||||||
|
})(window);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
<head>
|
||||||
|
<link rel="import" href="observatory_element.html">
|
||||||
|
</head>
|
||||||
|
<polymer-element name="collapsible-content" extends="observatory-element">
|
||||||
|
<template>
|
||||||
|
<div class="well row">
|
||||||
|
<a on-click="toggleDisplay"
|
||||||
|
class="btn muted unselectable">
|
||||||
|
Raw message... <i class="{{ iconClass }}"></i>
|
||||||
|
</a>
|
||||||
|
<div style="display: {{ displayValue }}" class="well">
|
||||||
|
<content></content>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script type="application/dart" src="collapsible_content.dart"></script>
|
||||||
|
</polymer-element>
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 469 B After Width: | Height: | Size: 469 B |
|
@ -0,0 +1,10 @@
|
||||||
|
<head>
|
||||||
|
<link rel="import" href="observatory_element.html">
|
||||||
|
<link rel="import" href="service_view.html">
|
||||||
|
</head>
|
||||||
|
<polymer-element name="response-viewer" extends="observatory-element">
|
||||||
|
<template>
|
||||||
|
<service-view object="{{ app.response }}"></service-view>
|
||||||
|
</template>
|
||||||
|
<script type="application/dart" src="response_viewer.dart"></script>
|
||||||
|
</polymer-element>
|
|
@ -0,0 +1,42 @@
|
||||||
|
<link rel="import" href="../../../../packages/polymer/polymer.html">
|
||||||
|
<link rel="import" href="curly_block.html">
|
||||||
|
<link rel="import" href="function_ref.html">
|
||||||
|
<link rel="import" href="instance_ref.html">
|
||||||
|
<link rel="import" href="observatory_element.html">
|
||||||
|
<link rel="import" href="script_ref.html">
|
||||||
|
|
||||||
|
<polymer-element name="stack-frame" extends="observatory-element">
|
||||||
|
<template>
|
||||||
|
<link rel="stylesheet" href="css/shared.css">
|
||||||
|
<div class="flex-row">
|
||||||
|
<div class="flex-item-fixed-1-12">
|
||||||
|
</div>
|
||||||
|
<div class="flex-item-fixed-1-12">
|
||||||
|
#{{ frame['depth'] }}
|
||||||
|
</div>
|
||||||
|
<div class="flex-item-fixed-9-12">
|
||||||
|
<function-ref ref="{{ frame['function'] }}"></function-ref>
|
||||||
|
( <script-ref ref="{{ frame['script'] }}"
|
||||||
|
pos="{{ frame['tokenPos'] }}">
|
||||||
|
</script-ref> )
|
||||||
|
|
||||||
|
<curly-block>
|
||||||
|
<div class="memberList">
|
||||||
|
<template repeat="{{ v in frame['vars'] }}">
|
||||||
|
<div class="memberItem">
|
||||||
|
<div class="memberName">{{ v['name']}}</div>
|
||||||
|
<div class="memberValue">
|
||||||
|
<any-service-ref ref="{{ v['value'] }}"></any-service-ref>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</curly-block>
|
||||||
|
</div>
|
||||||
|
<div class="flex-item-fixed-1-12">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</polymer-element>
|
||||||
|
|
||||||
|
<script type="application/dart" src="stack_frame.dart"></script>
|
|
@ -0,0 +1,33 @@
|
||||||
|
<link rel="import" href="../../../../packages/polymer/polymer.html">
|
||||||
|
<link rel="import" href="nav_bar.html">
|
||||||
|
<link rel="import" href="observatory_element.html">
|
||||||
|
<link rel="import" href="stack_frame.html">
|
||||||
|
|
||||||
|
<polymer-element name="stack-trace" extends="observatory-element">
|
||||||
|
<template>
|
||||||
|
<link rel="stylesheet" href="css/shared.css">
|
||||||
|
<nav-bar>
|
||||||
|
<top-nav-menu></top-nav-menu>
|
||||||
|
<isolate-nav-menu isolate="{{ trace.isolate }}"></isolate-nav-menu>
|
||||||
|
<nav-menu link="{{ trace.isolate.relativeLink('stacktrace') }}" anchor="stack trace" last="{{ true }}"></nav-menu>
|
||||||
|
<nav-refresh callback="{{ refresh }}"></nav-refresh>
|
||||||
|
<nav-control></nav-control>
|
||||||
|
</nav-bar>
|
||||||
|
<template if="{{ trace['members'].isEmpty }}">
|
||||||
|
<div class="content">
|
||||||
|
<em>No stack</em>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template if="{{ trace['members'].isNotEmpty }}">
|
||||||
|
<ul class="list-group">
|
||||||
|
<template repeat="{{ frame in trace['members'] }}">
|
||||||
|
<li class="list-group-item">
|
||||||
|
<stack-frame frame="{{ frame }}"></stack-frame>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</polymer-element>
|
||||||
|
|
||||||
|
<script type="application/dart" src="stack_trace.dart"></script>
|
|
@ -0,0 +1,133 @@
|
||||||
|
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
|
||||||
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
/// Experimental bootstrap to initialize polymer applications. This library is
|
||||||
|
/// not used by default, and may be replaced by Dart code in the near future.
|
||||||
|
///
|
||||||
|
/// This script contains logic to bootstrap polymer apps during development. It
|
||||||
|
/// internally discovers Dart script tags through HTML imports, and constructs
|
||||||
|
/// a new entrypoint for the application that is then launched in an isolate.
|
||||||
|
///
|
||||||
|
/// For each script tag found, we will load the corresponding Dart library and
|
||||||
|
/// execute all methods annotated with `@initMethod` and register all classes
|
||||||
|
/// labeled with `@CustomTag`. We keep track of the order of imports and execute
|
||||||
|
/// initializers in the same order.
|
||||||
|
///
|
||||||
|
/// You can this experimental bootstrap logic by including the
|
||||||
|
/// polymer_experimental.html import, instead of polymer.html:
|
||||||
|
///
|
||||||
|
/// <link rel="import" href="packages/polymer/polymer_experimental.html">
|
||||||
|
///
|
||||||
|
/// This bootstrap replaces `initPolymer` so Dart code might need to be changed
|
||||||
|
/// too. If you loaded init.dart directly, you can remove it. But if you invoke
|
||||||
|
/// initPolymer in your main, you should remove that call and change to use
|
||||||
|
/// `@initMethod` instead. The current bootstrap doesn't support having Dart
|
||||||
|
/// script tags in the main page, so you may need to move some code into an HTML
|
||||||
|
/// import. For example, If you need to run some initialization code before any
|
||||||
|
/// other code is executed, include an HTML import to an html file with a
|
||||||
|
/// "application/dart" script tag that contains an initializer
|
||||||
|
/// method with the body of your old main, and make sure this tag is placed
|
||||||
|
/// above other html-imports that load the rest of the application.
|
||||||
|
/// Initialization methods are executed in the order in which they are
|
||||||
|
/// discovered in the HTML document.
|
||||||
|
(function() {
|
||||||
|
// Only run in Dartium.
|
||||||
|
if (!navigator.dartEnabled &&
|
||||||
|
// TODO(sigmund): remove userAgent check once 1.6 rolls as stable.
|
||||||
|
// See: dartbug.com/18463
|
||||||
|
(navigator.userAgent.indexOf('(Dart)') === -1)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract a Dart import URL from a script tag, which is the 'src' attribute
|
||||||
|
// of the script tag, or a data-url with the script contents for inlined code.
|
||||||
|
function getScriptUrl(script) {
|
||||||
|
var url = script.src;
|
||||||
|
if (url) {
|
||||||
|
// Normalize package: urls
|
||||||
|
var index = url.indexOf('packages/');
|
||||||
|
if (index == 0 || (index > 0 && url[index - 1] == '/')) {
|
||||||
|
url = "package:" + url.slice(index + 9);
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(sigmund): change back to application/dart: using application/json is
|
||||||
|
// wrong but it hides a warning in Dartium (dartbug.com/18000).
|
||||||
|
return "data:application/json;base64," + window.btoa(script.textContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a Dart program that imports [urls] and passes them to
|
||||||
|
// startPolymerInDevelopment, which in turn will invoke methods marked with
|
||||||
|
// @initMethod, and register any custom tag labeled with @CustomTag in those
|
||||||
|
// libraries.
|
||||||
|
function createMain(urls, mainUrl) {
|
||||||
|
var imports = Array(urls.length + 1);
|
||||||
|
for (var i = 0; i < urls.length; ++i) {
|
||||||
|
imports[i] = 'import "' + urls[i] + '" as i' + i + ';';
|
||||||
|
}
|
||||||
|
imports[urls.length] = 'import "package:polymer/src/mirror_loader.dart";';
|
||||||
|
var arg = urls.length == 0 ? '[]' :
|
||||||
|
('[\n "' + urls.join('",\n "') + '"\n ]');
|
||||||
|
return (imports.join('\n') +
|
||||||
|
'\n\nmain() {\n' +
|
||||||
|
' startPolymerInDevelopment(' + arg + ');\n' +
|
||||||
|
'}\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
function discoverScripts(content, state, importedDoc) {
|
||||||
|
if (!state) {
|
||||||
|
// internal state tracking documents we've visited, the resulting list of
|
||||||
|
// scripts, and any tags with the incorrect mime-type.
|
||||||
|
state = {seen: {}, scripts: [], badTags: []};
|
||||||
|
}
|
||||||
|
if (!content) return state;
|
||||||
|
|
||||||
|
// Note: we visit both script and link-imports together to ensure we
|
||||||
|
// preserve the order of the script tags as they are discovered.
|
||||||
|
var nodes = content.querySelectorAll('script,link[rel="import"]');
|
||||||
|
for (var i = 0; i < nodes.length; i++) {
|
||||||
|
var node = nodes[i];
|
||||||
|
if (node instanceof HTMLLinkElement) {
|
||||||
|
// TODO(jmesserly): figure out why ".import" fails in content_shell but
|
||||||
|
// works in Dartium.
|
||||||
|
if (node.import && node.import.href) node = node.import;
|
||||||
|
|
||||||
|
if (state.seen[node.href]) continue;
|
||||||
|
state.seen[node.href] = node;
|
||||||
|
discoverScripts(node.import, state, true);
|
||||||
|
} else if (node instanceof HTMLScriptElement) {
|
||||||
|
if (node.type != 'application/dart') continue;
|
||||||
|
if (importedDoc) {
|
||||||
|
state.scripts.push(getScriptUrl(node));
|
||||||
|
} else {
|
||||||
|
state.badTags.push(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(jmesserly): we're using this function because DOMContentLoaded can
|
||||||
|
// be fired too soon: https://www.w3.org/Bugs/Public/show_bug.cgi?id=23526
|
||||||
|
HTMLImports.whenReady(function() {
|
||||||
|
// Append a new script tag that initializes everything.
|
||||||
|
var newScript = document.createElement('script');
|
||||||
|
newScript.type = "application/dart";
|
||||||
|
|
||||||
|
var results = discoverScripts(document);
|
||||||
|
if (results.badTags.length > 0) {
|
||||||
|
console.warn('The experimental polymer boostrap does not support '
|
||||||
|
+ 'having script tags in the main document. You can move the script '
|
||||||
|
+ 'tag to an HTML import instead. Also make sure your script tag '
|
||||||
|
+ 'doesn\'t have a main, but a top-level method marked with '
|
||||||
|
+ '@initMethod instead');
|
||||||
|
for (var i = 0; i < results.badTags.length; i++) {
|
||||||
|
console.warn(results.badTags[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newScript.textContent = createMain(results.scripts);
|
||||||
|
document.body.appendChild(newScript);
|
||||||
|
});
|
||||||
|
})();
|
|
@ -0,0 +1,21 @@
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This file is from the Polymer project (https://github.com/Polymer/polymer/).
|
||||||
|
You can replace polymer.html with a different version if desired.
|
||||||
|
-->
|
||||||
|
<!-- minified for deployment: -->
|
||||||
|
<link rel="import" href="src/js/polymer/polymer.html">
|
||||||
|
<script>
|
||||||
|
// TODO(sigmund): remove this script tag (dartbug.com/19650). This empty
|
||||||
|
// script tag is necessary to work around a bug in Chrome 36.
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- unminified for debugging:
|
||||||
|
<link rel="import" href="src/js/polymer/layout.html">
|
||||||
|
<script src="src/js/polymer/polymer.js"></script>
|
||||||
|
-->
|
|
@ -0,0 +1,9 @@
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<link rel="import" href="polymer.html">
|
||||||
|
|
||||||
|
<!-- Experimental: bootstrap the user application in a new isolate. -->
|
||||||
|
<script src="boot.js"></script>
|
|
@ -0,0 +1,545 @@
|
||||||
|
<!doctype html>
|
||||||
|
<!--
|
||||||
|
This file is autogenerated with polymer/tool/create_message_details_page.dart
|
||||||
|
-->
|
||||||
|
<html>
|
||||||
|
<style>
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Montserrat';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(https://themes.googleusercontent.com/static/fonts/montserrat/v4/zhcz-_WihjSQC0oHJ9TCYL3hpw3pgy2gAi-Ip7WPMi0.woff) format('woff');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Montserrat';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: url(https://themes.googleusercontent.com/static/fonts/montserrat/v4/IQHow_FEYlDC4Gzy_m8fcnbFhgvWbfSbdVg11QabG8w.woff) format('woff');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
src: url(https://themes.googleusercontent.com/static/fonts/roboto/v10/Hgo13k-tfSpn0qi1SFdUfbO3LdcAZYWl9Si6vvxL-qU.woff) format('woff');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(https://themes.googleusercontent.com/static/fonts/roboto/v10/CrYjSnGjrRCn0pd9VQsnFOvvDin1pK8aKteLpeZ5c0A.woff) format('woff');
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
width: 80vw;
|
||||||
|
margin: 20px;
|
||||||
|
font-family: Roboto, sans-serif;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-family: Montserrat, sans-serif;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: rgb(72, 72, 72);
|
||||||
|
display: block;
|
||||||
|
font-style: normal;
|
||||||
|
font-variant: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
div:target {
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #888;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 0px 10px 2px 10px;
|
||||||
|
box-shadow: 7px 7px 5px #888888;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-family: Montserrat, sans-serif;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: rgb(72, 72, 72);
|
||||||
|
display: block;
|
||||||
|
font-style: normal;
|
||||||
|
font-variant: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
div:target > h3 {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
display: block;
|
||||||
|
padding: 9.5px;
|
||||||
|
margin: 0 0 10px;
|
||||||
|
color: #333;
|
||||||
|
word-break: break-all;
|
||||||
|
word-wrap: break-word;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
font-family: Menlo,Monaco,Consolas,"Courier New",monospace;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0;
|
||||||
|
font-size: 90%;
|
||||||
|
color: #0084c5;
|
||||||
|
white-space: nowrap;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #f9f2f4;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre code {
|
||||||
|
white-space: inherit;
|
||||||
|
color: inherit;
|
||||||
|
background-color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: rgb(42, 100, 150);
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 > a {
|
||||||
|
display: none;
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3:hover > a {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<body>
|
||||||
|
<h2>Messages from package <code>code_transformers</code></h2>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div id="code_transformers_1"><h3>Absolute paths not allowed <a href="#code_transformers_1">#1</a></h3>
|
||||||
|
<p>The transformers processing your code were trying to resolve a URL and identify
|
||||||
|
a file that they correspond to. Currently only relative paths can be resolved.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="code_transformers_2"><h3>Invalid URL to reach another package <a href="#code_transformers_2">#2</a></h3>
|
||||||
|
<p>To reach an asset that belongs to another package, use <code>package:</code> URLs in
|
||||||
|
Dart code, but in any other language (like HTML or CSS) use relative URLs that
|
||||||
|
first go all the way to the <code>packages/</code> directory.</p>
|
||||||
|
<p>The rules for correctly writing these imports are subtle and have a lot of
|
||||||
|
special cases. Please review
|
||||||
|
<a href="https://www.dartlang.org/polymer/app-directories.html">https://www.dartlang.org/polymer/app-directories.html</a> to learn
|
||||||
|
more.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="code_transformers_3"><h3>Incomplete URL to asset in another package <a href="#code_transformers_3">#3</a></h3>
|
||||||
|
<p>URLs that refer to assets in other packages need to explicitly mention the
|
||||||
|
<code>packages/</code> directory. In the future this requirement might be removed, but for
|
||||||
|
now you must use a canonical URL form for it.</p>
|
||||||
|
<p>For example, if <code>packages/a/a.html</code> needs to import <code>packages/b/b.html</code>,
|
||||||
|
you might expect a.html to import <code>../b/b.html</code>. Instead, it must import
|
||||||
|
<code>../../packages/b/b.html</code>.</p>
|
||||||
|
<p>See <a href="http://dartbug.com/15797">issue 15797</a> and
|
||||||
|
<a href="https://www.dartlang.org/polymer/app-directories.html">https://www.dartlang.org/polymer/app-directories.html</a> to learn more.</p>
|
||||||
|
</div><hr /><h2>Messages from package <code>observe</code></h2>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div id="observe_1"><h3><code>@observable</code> not supported on libraries <a href="#observe_1">#1</a></h3>
|
||||||
|
<p>Only instance fields on <code>Observable</code> classes can be observable,
|
||||||
|
and you must explicitly annotate each observable field as <code>@observable</code>.</p>
|
||||||
|
<p>Support for using the <code>@observable</code> annotation in libraries, classes, and
|
||||||
|
elsewhere is deprecated.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="observe_2"><h3><code>@observable</code> not supported on top-level fields <a href="#observe_2">#2</a></h3>
|
||||||
|
<p>Only instance fields on <code>Observable</code> classes can be observable,
|
||||||
|
and you must explicitly annotate each observable field as <code>@observable</code>.</p>
|
||||||
|
<p>Support for using the <code>@observable</code> annotation in libraries, classes, and
|
||||||
|
elsewhere is deprecated.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="observe_3"><h3><code>@observable</code> not supported on classes <a href="#observe_3">#3</a></h3>
|
||||||
|
<p>Only instance fields on <code>Observable</code> classes can be observable,
|
||||||
|
and you must explicitly annotate each observable field as <code>@observable</code>.</p>
|
||||||
|
<p>Support for using the <code>@observable</code> annotation in libraries, classes, and
|
||||||
|
elsewhere is deprecated.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="observe_4"><h3><code>@observable</code> not supported on static fields <a href="#observe_4">#4</a></h3>
|
||||||
|
<p>Only instance fields on <code>Observable</code> classes can be observable,
|
||||||
|
and you must explicitly annotate each observable field as <code>@observable</code>.</p>
|
||||||
|
<p>Support for using the <code>@observable</code> annotation in libraries, classes, and
|
||||||
|
elsewhere is deprecated.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="observe_5"><h3><code>@observable</code> field not in an <code>Observable</code> class <a href="#observe_5">#5</a></h3>
|
||||||
|
<p>Only instance fields on <code>Observable</code> classes can be observable,
|
||||||
|
and you must explicitly annotate each observable field as <code>@observable</code>.</p>
|
||||||
|
<p>Support for using the <code>@observable</code> annotation in libraries, classes, and
|
||||||
|
elsewhere is deprecated.</p>
|
||||||
|
</div><hr /><h2>Messages from package <code>polymer</code></h2>
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div id="polymer_1"><h3>Import not found <a href="#polymer_1">#1</a></h3>
|
||||||
|
<p>An HTML import seems to be broken. This could be because the file doesn't exist
|
||||||
|
or because the link URL is incorrect.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_2"><h3>Duplicate definition <a href="#polymer_2">#2</a></h3>
|
||||||
|
<p>Custom element names are global and can only be defined once. Some common
|
||||||
|
reasons why you might get two definitions:</p><ul><li>Two different elements are declared with the same name.</li><li>
|
||||||
|
<p>A single HTML file defining an element, has been imported using two different
|
||||||
|
URLs.</p></li></ul>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_3"><h3>Missing import to polymer.html <a href="#polymer_3">#3</a></h3>
|
||||||
|
<p>Starting with polymer 0.11.0, each file that uses the definition
|
||||||
|
of polymer-element must import it either directly or transitively.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_4"><h3>Invalid import inside <polymer-element> <a href="#polymer_4">#4</a></h3>
|
||||||
|
<p>HTML imports are expected at the top of each document, outside of any
|
||||||
|
polymer-element definitions. The polymer build process combines all your HTML
|
||||||
|
files together so you can deploy a single HTML file with your application. This
|
||||||
|
build process ignores imports that appear to be in the wrong location.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_5"><h3>Missing call to <code>initPolymer()</code> <a href="#polymer_5">#5</a></h3>
|
||||||
|
<p>Your application entry point didn't have any Dart script tags, so it's missing
|
||||||
|
some initialization needed for polymer.dart.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_6"><h3>Script tags with experimental bootstrap <a href="#polymer_6">#6</a></h3>
|
||||||
|
<p>This experimental feature is no longer supported.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_7"><h3>Multiple Dart script tags per document <a href="#polymer_7">#7</a></h3>
|
||||||
|
<p>Dartium currently allows only one script tag per document. Any
|
||||||
|
additional script tags might be ignored or result in an error. This will
|
||||||
|
likely change in the future, but for now, combine the script tags together into
|
||||||
|
a single Dart library.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_8"><h3>Imports before script tags <a href="#polymer_8">#8</a></h3>
|
||||||
|
<p>It is good practice to put all your HTML imports at the beginning of the
|
||||||
|
document, above any Dart script tags. Today, the execution of Dart script tags
|
||||||
|
is not synchronous in Dartium, so the difference is not noticeable. However,
|
||||||
|
Dartium that will eventually change and make the timing of script tags execution
|
||||||
|
match how they are in JavaScript. At that point the order of your imports with
|
||||||
|
respect to script tags will be important. Following the practice of putting
|
||||||
|
imports first protects your app from a future breaking change in this respect.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_9"><h3>Missing href on a <code><link></code> tag <a href="#polymer_9">#9</a></h3>
|
||||||
|
<p>All <code><link></code> tags should have a valid URL to a resource.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_10"><h3><code><element></code> is deprecated <a href="#polymer_10">#10</a></h3>
|
||||||
|
<p>Long ago <code><polymer-element></code> used to be called <code><element></code>. You probably ran
|
||||||
|
into this error if you were migrating code that was written on a very early
|
||||||
|
version of polymer.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_11"><h3>Definition of a custom element not found <a href="#polymer_11">#11</a></h3>
|
||||||
|
<p>The polymer build was not able to find the definition of a custom element. This
|
||||||
|
can happen if an element is defined with a <code><polymer-element></code> tag, but you are
|
||||||
|
missing an HTML import or the import link is incorrect.</p>
|
||||||
|
<p>This warning can also be a false alarm. For instance, when an element is defined
|
||||||
|
programatically using <code>document.registerElement</code>. In that case the polymer build
|
||||||
|
will not be able to see the definition and will produce this warning.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_12"><h3>Empty script tag <a href="#polymer_12">#12</a></h3>
|
||||||
|
<p>Script tags should either have a <code>src</code> attribute or a non-empty body.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_13"><h3>Expected Dart mime-type <a href="#polymer_13">#13</a></h3>
|
||||||
|
<p>You seem to have a <code>.dart</code> extension on a script tag, but the mime-type
|
||||||
|
doesn't match <code>application/dart</code>.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_14"><h3>Expected Dart file extension <a href="#polymer_14">#14</a></h3>
|
||||||
|
<p>You are using the <code>application/dart</code> mime-type on a script tag, so
|
||||||
|
the URL to the script source URL should have a <code>.dart</code> extension.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_15"><h3>Script with both src and inline text <a href="#polymer_15">#15</a></h3>
|
||||||
|
<p>You have a script tag that includes both a <code>src</code> attribute and inline script
|
||||||
|
text. You must choose one or the other.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_16"><h3>Incorrect instantiation: missing base tag in instantiation <a href="#polymer_16">#16</a></h3>
|
||||||
|
<p>When you declare that a custom element extends from a base tag, for example:</p>
|
||||||
|
<pre><code><polymer-element name="my-example" extends="ul">
|
||||||
|
</code></pre>
|
||||||
|
<p>or:</p>
|
||||||
|
<pre><code><polymer-element name="my-example2" extends="ul">
|
||||||
|
<polymer-element name="my-example" extends="my-example2">
|
||||||
|
</code></pre>
|
||||||
|
<p>You should instantiate <code>my-example</code> by using this syntax:</p>
|
||||||
|
<pre><code><ul is="my-example">
|
||||||
|
</code></pre>
|
||||||
|
<p>And not:</p>
|
||||||
|
<pre><code><my-example>
|
||||||
|
</code></pre>
|
||||||
|
<p>Only elements that don't extend from existing HTML elements are created using
|
||||||
|
the latter form.</p>
|
||||||
|
<p>This is because browsers first create the base element, and then upgrade it to
|
||||||
|
have the extra functionality of your custom element. In the example above, using
|
||||||
|
<code><ul></code> tells the browser which base type it must create before
|
||||||
|
doing the upgrade.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_17"><h3>Incorrect instantiation: extra <code>is</code> attribute or missing <code>extends</code> in declaration <a href="#polymer_17">#17</a></h3>
|
||||||
|
<p>Creating a custom element using the syntax:</p>
|
||||||
|
<pre><code><ul is="my-example">
|
||||||
|
</code></pre>
|
||||||
|
<p>means that the declaration of <code>my-example</code> extends transitively from <code>ul</code>. This
|
||||||
|
error message is shown if the definition of <code>my-example</code> doesn't declare this
|
||||||
|
extension. It might be that you no longer extend from the base element, in which
|
||||||
|
case the fix is to change the instantiation to:</p>
|
||||||
|
<pre><code><my-example>
|
||||||
|
</code></pre>
|
||||||
|
<p>Another possibility is that the declaration needs to be fixed to include the
|
||||||
|
<code>extends</code> attribute, for example:</p>
|
||||||
|
<pre><code><polymer-element name="my-example" extends="ul">
|
||||||
|
</code></pre>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_18"><h3>Incorrect instantiation: base tag seems wrong <a href="#polymer_18">#18</a></h3>
|
||||||
|
<p>It seems you have a declaration like:</p>
|
||||||
|
<pre><code><polymer-element name="my-example" extends="div">
|
||||||
|
</code></pre>
|
||||||
|
<p>but an instantiation like:</p>
|
||||||
|
<pre><code><span is="my-example">
|
||||||
|
</code></pre>
|
||||||
|
<p>Both the declaration and the instantiation need to match on the base type. So
|
||||||
|
either the instantiation needs to be fixed to be more like:</p>
|
||||||
|
<pre><code><span is="my-example">
|
||||||
|
</code></pre>
|
||||||
|
<p>or the declaration should be fixed to be like:</p>
|
||||||
|
<pre><code><polymer-element name="my-example" extends="span">
|
||||||
|
</code></pre>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_19"><h3>No dashes allowed in custom attributes <a href="#polymer_19">#19</a></h3>
|
||||||
|
<p>Polymer used to recognize attributes with dashes like <code>my-name</code> and convert them
|
||||||
|
to match properties where dashes were removed, and words follow the camelCase
|
||||||
|
style (for example <code>myName</code>). This feature is no longer available. Now simply
|
||||||
|
use the same name as the property.</p>
|
||||||
|
<p>Because HTML attributes are case-insensitive, you can also write the name of
|
||||||
|
your property entirely in lowercase. Just be sure that your custom-elements
|
||||||
|
don't declare two properties with the same name but different capitalization.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_20"><h3>Event handlers not supported here <a href="#polymer_20">#20</a></h3>
|
||||||
|
<p>Bindings of the form <code>{{ }}</code> are supported inside <code><template></code> nodes, even outside
|
||||||
|
of <code><polymer-element></code> declarations. However, those bindings only support binding
|
||||||
|
values into the content of a node or an attribute.</p>
|
||||||
|
<p>Inline event handlers of the form <code>on-click="{{method}}"</code> are a special feature
|
||||||
|
of polymer elements, so they are only supported inside <code><polymer-element></code>
|
||||||
|
definitions.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_21"><h3>No expressions allowed in event handler bindings <a href="#polymer_21">#21</a></h3>
|
||||||
|
<p>Unlike data bindings, event handler bindings of the form <code>on-click="{{method}}"</code>
|
||||||
|
are not evaluated as expressions. They are meant to just contain a simple name
|
||||||
|
that resolves to a method in your polymer element's class definition.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_22"><h3>Nested polymer element definitions not allowed <a href="#polymer_22">#22</a></h3>
|
||||||
|
<p>Because custom element names are global, there is no need to have a
|
||||||
|
<code><polymer-element></code> definition nested within a <code><polymer-element></code>. If you have
|
||||||
|
a definition inside another, move the second definition out.</p>
|
||||||
|
<p>You might see this error if you have an HTML import within a polymer element.
|
||||||
|
You should be able to move the import out of the element definition.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_23"><h3>Polymer element definitions without a name <a href="#polymer_23">#23</a></h3>
|
||||||
|
<p>Polymer element definitions must have a name. You can include a name by using
|
||||||
|
the <code>name</code> attribute in <code><polymer-element></code> for example:</p>
|
||||||
|
<pre><code><polymer-element name="my-example">
|
||||||
|
</code></pre>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_24"><h3>Custom element name missing a dash <a href="#polymer_24">#24</a></h3>
|
||||||
|
<p>Custom element names must have a dash (<code>-</code>) and can't be any of the following
|
||||||
|
reserved names:</p><ul><li><code>annotation-xml</code></li><li><code>color-profile</code></li><li><code>font-face</code></li><li><code>font-face-src</code></li><li><code>font-face-uri</code></li><li><code>font-face-format</code></li><li><code>font-face-name</code></li><li><code>missing-glyph</code></li></ul>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_25"><h3>Error while inlining an import <a href="#polymer_25">#25</a></h3>
|
||||||
|
<p>An error occurred while inlining an import in the polymer build. This is often
|
||||||
|
the result of a broken HTML import.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_26"><h3>Error while inlining a stylesheet <a href="#polymer_26">#26</a></h3>
|
||||||
|
<p>An error occurred while inlining a stylesheet in the polymer build. This is
|
||||||
|
often the result of a broken URL in a <code><link rel="stylesheet" href="..."></code>.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_27"><h3>URL to a script file might be incorrect <a href="#polymer_27">#27</a></h3>
|
||||||
|
<p>An error occurred trying to read a script tag on a given URL. This is often the
|
||||||
|
result of a broken URL in a <code><script src="..."></code>.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_28"><h3>Attribute missing "_" prefix <a href="#polymer_28">#28</a></h3>
|
||||||
|
<p>Not all browsers support bindings to certain attributes, especially URL
|
||||||
|
attributes. Some browsers might sanitize attributes and result in an
|
||||||
|
incorrect value. For this reason polymer provides a special set of attributes
|
||||||
|
that let you bypass any browser internal attribute validation. The name of the
|
||||||
|
attribute is the same as the original attribute, but with a leading underscore.
|
||||||
|
For example, instead of writing:</p>
|
||||||
|
<pre><code><img src="{{binding}}">
|
||||||
|
</code></pre>
|
||||||
|
<p>you can write:</p>
|
||||||
|
<pre><code><img _src="{{binding}}">
|
||||||
|
</code></pre>
|
||||||
|
<p>For more information, see <a href="http://goo.gl/5av8cU">http://goo.gl/5av8cU</a>.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_29"><h3>Attribute with extra "_" prefix <a href="#polymer_29">#29</a></h3>
|
||||||
|
<p>A special attribute exists to support bindings on URL attributes. For example,
|
||||||
|
this correctly binds the <code>src</code> attribute in an image:</p>
|
||||||
|
<pre><code><img _src="{{binding}}">
|
||||||
|
</code></pre>
|
||||||
|
<p>However, this special <code>_src</code> attribute is only available for bindings. If you
|
||||||
|
just have a URL, use the normal <code>src</code> attribute instead.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_30"><h3>Internal error: don't know how to include a URL <a href="#polymer_30">#30</a></h3>
|
||||||
|
<p>Sorry, you just ran into a bug in the polymer transformer code. Please file a
|
||||||
|
bug at <a href="http://dartbug.com/new">http://dartbug.com/new</a> including, if possible, some example code that
|
||||||
|
can help the team reproduce the issue.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_31"><h3>Internal error: phases run out of order <a href="#polymer_31">#31</a></h3>
|
||||||
|
<p>Sorry, you just ran into a bug in the polymer transformer code. Please file a
|
||||||
|
bug at <a href="http://dartbug.com/new">http://dartbug.com/new</a> including, if possible, some example code that
|
||||||
|
can help the team reproduce the issue.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_32"><h3><code>@CustomTag</code> used on a private class <a href="#polymer_32">#32</a></h3>
|
||||||
|
<p>The <code>@CustomTag</code> annotation is currently only supported on public classes. If
|
||||||
|
you need to register a custom element whose implementation is a private class
|
||||||
|
(that is, a class whose name starts with <code>_</code>), you can still do so by invoking
|
||||||
|
<code>Polymer.register</code> within a public method marked with <code>@initMethod</code>.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_33"><h3><code>@initMethod</code> is on a private function <a href="#polymer_33">#33</a></h3>
|
||||||
|
<p>The <code>@initMethod</code> annotation is currently only supported on public top-level
|
||||||
|
functions.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_34"><h3>Missing argument in annotation <a href="#polymer_34">#34</a></h3>
|
||||||
|
<p>The annotation expects one argument, but the argument was not provided.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_35"><h3>Invalid argument in annotation <a href="#polymer_35">#35</a></h3>
|
||||||
|
<p>The polymer transformer was not able to extract a constant value for the
|
||||||
|
annotation argument. This can happen if your code is currently in a state that
|
||||||
|
can't be analyzed (for example, it has parse errors) or if the expression passed
|
||||||
|
as an argument is invalid (for example, it is not a compile-time constant).</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_36"><h3>No polymer initializers found <a href="#polymer_36">#36</a></h3>
|
||||||
|
<p>No polymer initializers were found. Make sure to either
|
||||||
|
annotate your polymer elements with @CustomTag or include a
|
||||||
|
top level method annotated with @initMethod that registers your
|
||||||
|
elements. Both annotations are defined in the polymer library (
|
||||||
|
package:polymer/polymer.dart).</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_37"><h3>Event bindings with @ are no longer supported <a href="#polymer_37">#37</a></h3>
|
||||||
|
<p>For a while there was an undocumented feature that allowed users to include
|
||||||
|
expressions in event bindings using the <code>@</code> prefix, for example:</p>
|
||||||
|
<pre><code><div on-click="{{@a.b.c}}">
|
||||||
|
|
||||||
|
</code></pre>
|
||||||
|
<p>This feature is no longer supported.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_38"><h3>Private symbol in event handler <a href="#polymer_38">#38</a></h3>
|
||||||
|
<p>Currently private members can't be used in event handler bindings. So you can't
|
||||||
|
write:</p>
|
||||||
|
<pre><code><div on-click="{{_method}}">
|
||||||
|
</code></pre>
|
||||||
|
<p>This restriction might be removed in the future, but for now, you need to make
|
||||||
|
your event handlers public.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_39"><h3>Private symbol in binding expression <a href="#polymer_39">#39</a></h3>
|
||||||
|
<p>Private members can't be used in binding expressions. For example, you can't
|
||||||
|
write:</p>
|
||||||
|
<pre><code><div>{{a.b._c}}</div>
|
||||||
|
</code></pre>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_40"><h3>A warning was found while parsing the HTML document <a href="#polymer_40">#40</a></h3>
|
||||||
|
<p>The polymer transformer uses a parser that implements the HTML5 spec
|
||||||
|
(<code>html5lib</code>). This message reports a
|
||||||
|
warning that the parser detected.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_41"><h3>Possible flash of unstyled content <a href="#polymer_41">#41</a></h3>
|
||||||
|
<p>Custom element found in document body without an "unresolved" attribute on it or
|
||||||
|
one of its parents. This means your app probably has a flash of unstyled content
|
||||||
|
before it finishes loading. See <a href="http://goo.gl/iN03Pj">http://goo.gl/iN03Pj</a> for more info.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_42"><h3>A css file was inlined multiple times. <a href="#polymer_42">#42</a></h3>
|
||||||
|
<p>Css files are inlined by default, but if you import the same one in multiple
|
||||||
|
places you probably want to override this behavior to prevent duplicate code.
|
||||||
|
To do this, use the following pattern to update your pubspec.yaml:</p>
|
||||||
|
<pre><code>transformers:
|
||||||
|
- polymer:
|
||||||
|
inline_stylesheets:
|
||||||
|
web/my_file.css: false
|
||||||
|
</code></pre>
|
||||||
|
<p>If you would like to hide this warning and keep it inlined, do the same thing
|
||||||
|
but assign the value to true.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_43"><h3>"dart_support.js" injected automatically <a href="#polymer_43">#43</a></h3>
|
||||||
|
<p>The script <code>packages/web_components/dart_support.js</code> is still used, but you no
|
||||||
|
longer need to put it in your application's entrypoint.</p>
|
||||||
|
<p>In the past this file served two purposes:</p><ul><li>to make dart2js work well with the web_components polyfills, and</li><li>to support registering Dart APIs for JavaScript custom elements.</li></ul>
|
||||||
|
<p>Now, the code from <code>dart_support.js</code> is split in two halves. The half for
|
||||||
|
dart2js is now injected by the polymer transformers automatically during <code>pub
|
||||||
|
build</code>. The <code>web_components</code> package provides an HTML file containing the other
|
||||||
|
half. Developers of packages that wrap JavaScript custom elements (like
|
||||||
|
<code>core_elements</code> and <code>paper_elements</code>) will import that file directly, so
|
||||||
|
application developers don't have to worry about it anymore.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_44"><h3>Dart script file included more than once. <a href="#polymer_44">#44</a></h3>
|
||||||
|
<p>Duplicate dart scripts often happen if you have multiple html imports that
|
||||||
|
include the same script. The simplest workaround for this is to move your dart
|
||||||
|
script to its own html file, and import that instead of the script (html imports
|
||||||
|
are automatically deduped).</p>
|
||||||
|
<p>For example:</p>
|
||||||
|
<pre><code><script type="application/dart" src="foo.dart"></script>
|
||||||
|
</code></pre>
|
||||||
|
<p>Should turn into:</p>
|
||||||
|
<pre><code><link rel="import" href="foo.html">
|
||||||
|
</code></pre>
|
||||||
|
<p>And <code>foo.html</code> should look like:</p>
|
||||||
|
<pre><code><script type="application/dart" src="foo.dart"></script>
|
||||||
|
</code></pre>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_45"><h3>"webcomponents.js" injected automatically <a href="#polymer_45">#45</a></h3>
|
||||||
|
<p>The script <code>packages/web_components/webcomponents.js</code> is still used, but you no
|
||||||
|
longer need to put it in your application's entrypoint.</p>
|
||||||
|
<p>The polyfills provided by this file are no longer required in chrome and will
|
||||||
|
automatically be added during <code>pub build</code> and <code>pub serve</code>.</p>
|
||||||
|
</div><hr />
|
||||||
|
|
||||||
|
<div id="polymer_46"><h3>"platform.js" renamed to "webcomponents.js". <a href="#polymer_46">#46</a></h3>
|
||||||
|
<p>The script <code>packages/web_components/platform.js</code> has been renamed to
|
||||||
|
<code>packages/web_components/webcomponents.js</code>. This is automatically fixed in
|
||||||
|
<code>pub serve</code> and <code>pub build</code> but we may remove this functionality in the next
|
||||||
|
breaking version of Polymer.</p>
|
||||||
|
<p>In addition, it is no longer required that you include this file directly, as
|
||||||
|
<code>pub build</code> and <code>pub serve</code> will inject it for you, and its not required when
|
||||||
|
running in dartium with a local server.</p>
|
||||||
|
</div><hr /></body>
|
||||||
|
</html>
|
|
@ -0,0 +1,9 @@
|
||||||
|
# Names should be added to this file with this pattern:
|
||||||
|
#
|
||||||
|
# For individuals:
|
||||||
|
# Name <email address>
|
||||||
|
#
|
||||||
|
# For organizations:
|
||||||
|
# Organization <fnmatch pattern>
|
||||||
|
#
|
||||||
|
Google Inc. <*@google.com>
|
|
@ -0,0 +1,73 @@
|
||||||
|
# Contributing
|
||||||
|
|
||||||
|
Want to contribute to Polymer? Great!
|
||||||
|
|
||||||
|
We are more than happy to accept external contributions to the project in the form of [feedback](https://groups.google.com/forum/?fromgroups=#!forum/polymer-dev), [bug reports](../../issues), and pull requests.
|
||||||
|
|
||||||
|
## Contributor License Agreement
|
||||||
|
|
||||||
|
Before we can accept patches, there's a quick web form you need to fill out.
|
||||||
|
|
||||||
|
- If you're contributing as an individual (e.g. you own the intellectual property), fill out [this form](http://code.google.com/legal/individual-cla-v1.0.html).
|
||||||
|
- If you're contributing under a company, fill out [this form](http://code.google.com/legal/corporate-cla-v1.0.html) instead.
|
||||||
|
|
||||||
|
This CLA asserts that contributions are owned by you and that we can license all work under our [license](LICENSE).
|
||||||
|
|
||||||
|
Other projects require a similar agreement: jQuery, Firefox, Apache, Node, and many more.
|
||||||
|
|
||||||
|
[More about CLAs](https://www.google.com/search?q=Contributor%20License%20Agreement)
|
||||||
|
|
||||||
|
## Initial setup
|
||||||
|
|
||||||
|
Here's an easy guide that should get you up and running:
|
||||||
|
|
||||||
|
1. Setup Grunt: `sudo npm install -g grunt-cli`
|
||||||
|
1. Fork the project on github and pull down your copy.
|
||||||
|
> replace the {{ username }} with your username and {{ repository }} with the repository name
|
||||||
|
|
||||||
|
git clone git@github.com:{{ username }}/{{ repository }}.git --recursive
|
||||||
|
|
||||||
|
Note the `--recursive`. This is necessary for submodules to initialize properly. If you don't do a recursive clone, you'll have to init them manually:
|
||||||
|
|
||||||
|
git submodule init
|
||||||
|
git submodule update
|
||||||
|
|
||||||
|
Download and run the `pull-all.sh` script to install the sibling dependencies.
|
||||||
|
|
||||||
|
git clone git://github.com/Polymer/tools.git && tools/bin/pull-all.sh
|
||||||
|
|
||||||
|
1. Test your change
|
||||||
|
> in the repo you've made changes to, run the tests:
|
||||||
|
|
||||||
|
cd $REPO
|
||||||
|
npm install
|
||||||
|
grunt test
|
||||||
|
|
||||||
|
1. Commit your code and make a pull request.
|
||||||
|
|
||||||
|
That's it for the one time setup. Now you're ready to make a change.
|
||||||
|
|
||||||
|
## Submitting a pull request
|
||||||
|
|
||||||
|
We iterate fast! To avoid potential merge conflicts, it's a good idea to pull from the main project before making a change and submitting a pull request. The easiest way to do this is setup a remote called `upstream` and do a pull before working on a change:
|
||||||
|
|
||||||
|
git remote add upstream git://github.com/Polymer/{{ repository }}.git
|
||||||
|
|
||||||
|
Then before making a change, do a pull from the upstream `master` branch:
|
||||||
|
|
||||||
|
git pull upstream master
|
||||||
|
|
||||||
|
To make life easier, add a "pull upstream" alias in your `.gitconfig`:
|
||||||
|
|
||||||
|
[alias]
|
||||||
|
pu = !"git fetch origin -v; git fetch upstream -v; git merge upstream/master"
|
||||||
|
|
||||||
|
That will pull in changes from your forked repo, the main (upstream) repo, and merge the two. Then it's just a matter of running `git pu` before a change and pushing to your repo:
|
||||||
|
|
||||||
|
git checkout master
|
||||||
|
git pu
|
||||||
|
# make change
|
||||||
|
git commit -a -m 'Awesome things.'
|
||||||
|
git push
|
||||||
|
|
||||||
|
Lastly, don't forget to submit the pull request.
|
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright (c) 2014 The Polymer Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,23 @@
|
||||||
|
Additional IP Rights Grant (Patents)
|
||||||
|
|
||||||
|
"This implementation" means the copyrightable works distributed by
|
||||||
|
Google as part of the Polymer project.
|
||||||
|
|
||||||
|
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||||
|
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||||
|
patent license to make, have made, use, offer to sell, sell, import,
|
||||||
|
transfer and otherwise run, modify and propagate the contents of this
|
||||||
|
implementation of Polymer, where such license applies only to those
|
||||||
|
patent claims, both currently owned or controlled by Google and acquired
|
||||||
|
in the future, licensable by Google that are necessarily infringed by
|
||||||
|
this implementation of Polymer. This grant does not include claims
|
||||||
|
that would be infringed only as a consequence of further modification of
|
||||||
|
this implementation. If you or your agent or exclusive licensee
|
||||||
|
institute or order or agree to the institution of patent litigation
|
||||||
|
against any entity (including a cross-claim or counterclaim in a
|
||||||
|
lawsuit) alleging that this implementation of Polymer or any code
|
||||||
|
incorporated within this implementation of Polymer constitutes
|
||||||
|
direct or contributory patent infringement, or inducement of patent
|
||||||
|
infringement, then any patent rights granted to you under this License
|
||||||
|
for this implementation of Polymer shall terminate as of the date
|
||||||
|
such litigation is filed.
|
|
@ -0,0 +1,17 @@
|
||||||
|
# Polymer
|
||||||
|
|
||||||
|
[![Analytics](https://ga-beacon.appspot.com/UA-39334307-2/Polymer/polymer/README)](https://github.com/igrigorik/ga-beacon)
|
||||||
|
|
||||||
|
Build Status: [http://build.chromium.org/p/client.polymer/waterfall](http://build.chromium.org/p/client.polymer/waterfall)
|
||||||
|
|
||||||
|
## Brief Overview
|
||||||
|
|
||||||
|
For more detailed info goto [http://polymer-project.org/](http://polymer-project.org/).
|
||||||
|
|
||||||
|
Polymer is a new type of library for the web, designed to leverage the existing browser infrastructure to provide the encapsulation and extendability currently only available in JS libraries.
|
||||||
|
|
||||||
|
Polymer is based on a set of future technologies, including [Shadow DOM](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html), [Custom Elements](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html) and Model Driven Views. Currently these technologies are implemented as polyfills or shims, but as browsers adopt these features natively, the platform code that drives Polymer evacipates, leaving only the value-adds.
|
||||||
|
|
||||||
|
## Tools & Testing
|
||||||
|
|
||||||
|
For running tests or building minified files, consult the [tooling information](http://www.polymer-project.org/resources/tooling-strategy.html).
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"name": "polymer",
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"platform": "Polymer/platform#>=0.3.0 <1.0.0",
|
||||||
|
"core-component-page": "Polymer/core-component-page#>=0.3.0 <1.0.0"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
BUILD LOG
|
||||||
|
---------
|
||||||
|
Build Time: 2014-10-07T17:56:07
|
||||||
|
|
||||||
|
NODEJS INFORMATION
|
||||||
|
==================
|
||||||
|
nodejs: v0.10.21
|
||||||
|
chai: 1.9.1
|
||||||
|
grunt-concat-sourcemap: 0.4.3
|
||||||
|
grunt: 0.4.5
|
||||||
|
grunt-contrib-concat: 0.4.0
|
||||||
|
grunt-contrib-uglify: 0.5.1
|
||||||
|
grunt-string-replace: 0.2.7
|
||||||
|
grunt-audit: 0.0.3
|
||||||
|
grunt-contrib-yuidoc: 0.5.2
|
||||||
|
karma: 0.12.19
|
||||||
|
karma-chrome-launcher: 0.1.4
|
||||||
|
grunt-karma: 0.8.3
|
||||||
|
karma-firefox-launcher: 0.1.3
|
||||||
|
karma-crbot-reporter: 0.0.4
|
||||||
|
karma-mocha: 0.1.6
|
||||||
|
karma-ie-launcher: 0.1.5
|
||||||
|
mocha: 1.20.1
|
||||||
|
karma-safari-launcher: 0.1.1
|
||||||
|
karma-script-launcher: 0.1.0
|
||||||
|
|
||||||
|
REPO REVISIONS
|
||||||
|
==============
|
||||||
|
polymer-gestures: 93902f7166ae932503450441641e352b5205afa2
|
||||||
|
polymer-expressions: 9f1748ec7b34b445c29941920962ea3eac8e9b80
|
||||||
|
HTMLImports: 6dea2dd969dc4dfb594ae33d4b072130c4890da5
|
||||||
|
observe-js: fa70c37099026225876f7c7a26bdee7c48129f1c
|
||||||
|
NodeBind: a3e4046d5d6e240945abea02dd70ae596e7b1110
|
||||||
|
TemplateBinding: 41e95ea0e4b45543a29ea5240cd4f0defc7208c1
|
||||||
|
|
||||||
|
BUILD HASHES
|
||||||
|
============
|
||||||
|
build/polymer.js: fba96097f878a55bc1fefd1b157fdb0c60225eb7
|
|
@ -0,0 +1,286 @@
|
||||||
|
<!--
|
||||||
|
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 shim-shadowdom>
|
||||||
|
/*******************************
|
||||||
|
Flex Layout
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
html /deep/ [layout][horizontal], html /deep/ [layout][vertical] {
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [layout][horizontal][inline], html /deep/ [layout][vertical][inline] {
|
||||||
|
display: -ms-inline-flexbox;
|
||||||
|
display: -webkit-inline-flex;
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [layout][horizontal] {
|
||||||
|
-ms-flex-direction: row;
|
||||||
|
-webkit-flex-direction: row;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [layout][horizontal][reverse] {
|
||||||
|
-ms-flex-direction: row-reverse;
|
||||||
|
-webkit-flex-direction: row-reverse;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [layout][vertical] {
|
||||||
|
-ms-flex-direction: column;
|
||||||
|
-webkit-flex-direction: column;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [layout][vertical][reverse] {
|
||||||
|
-ms-flex-direction: column-reverse;
|
||||||
|
-webkit-flex-direction: column-reverse;
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [layout][wrap] {
|
||||||
|
-ms-flex-wrap: wrap;
|
||||||
|
-webkit-flex-wrap: wrap;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [layout][wrap-reverse] {
|
||||||
|
-ms-flex-wrap: wrap-reverse;
|
||||||
|
-webkit-flex-wrap: wrap-reverse;
|
||||||
|
flex-wrap: wrap-reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [flex] {
|
||||||
|
-ms-flex: 1 1 0.000000001px;
|
||||||
|
-webkit-flex: 1;
|
||||||
|
flex: 1;
|
||||||
|
-webkit-flex-basis: 0.000000001px;
|
||||||
|
flex-basis: 0.000000001px;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [vertical][layout] > [flex][auto-vertical], html /deep/ [vertical][layout]::shadow [flex][auto-vertical] {
|
||||||
|
-ms-flex: 1 1 auto;
|
||||||
|
-webkit-flex-basis: auto;
|
||||||
|
flex-basis: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [flex][auto] {
|
||||||
|
-ms-flex: 1 1 auto;
|
||||||
|
-webkit-flex-basis: auto;
|
||||||
|
flex-basis: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [flex][none] {
|
||||||
|
-ms-flex: none;
|
||||||
|
-webkit-flex: none;
|
||||||
|
flex: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [flex][one] {
|
||||||
|
-ms-flex: 1;
|
||||||
|
-webkit-flex: 1;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [flex][two] {
|
||||||
|
-ms-flex: 2;
|
||||||
|
-webkit-flex: 2;
|
||||||
|
flex: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [flex][three] {
|
||||||
|
-ms-flex: 3;
|
||||||
|
-webkit-flex: 3;
|
||||||
|
flex: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [flex][four] {
|
||||||
|
-ms-flex: 4;
|
||||||
|
-webkit-flex: 4;
|
||||||
|
flex: 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [flex][five] {
|
||||||
|
-ms-flex: 5;
|
||||||
|
-webkit-flex: 5;
|
||||||
|
flex: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [flex][six] {
|
||||||
|
-ms-flex: 6;
|
||||||
|
-webkit-flex: 6;
|
||||||
|
flex: 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [flex][seven] {
|
||||||
|
-ms-flex: 7;
|
||||||
|
-webkit-flex: 7;
|
||||||
|
flex: 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [flex][eight] {
|
||||||
|
-ms-flex: 8;
|
||||||
|
-webkit-flex: 8;
|
||||||
|
flex: 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [flex][nine] {
|
||||||
|
-ms-flex: 9;
|
||||||
|
-webkit-flex: 9;
|
||||||
|
flex: 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [flex][ten] {
|
||||||
|
-ms-flex: 10;
|
||||||
|
-webkit-flex: 10;
|
||||||
|
flex: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [flex][eleven] {
|
||||||
|
-ms-flex: 11;
|
||||||
|
-webkit-flex: 11;
|
||||||
|
flex: 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [flex][twelve] {
|
||||||
|
-ms-flex: 12;
|
||||||
|
-webkit-flex: 12;
|
||||||
|
flex: 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* alignment in cross axis */
|
||||||
|
|
||||||
|
html /deep/ [layout][start] {
|
||||||
|
-ms-flex-align: start;
|
||||||
|
-webkit-align-items: flex-start;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [layout][center], html /deep/ [layout][center-center] {
|
||||||
|
-ms-flex-align: center;
|
||||||
|
-webkit-align-items: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [layout][end] {
|
||||||
|
-ms-flex-align: end;
|
||||||
|
-webkit-align-items: flex-end;
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* alignment in main axis */
|
||||||
|
|
||||||
|
html /deep/ [layout][start-justified] {
|
||||||
|
-ms-flex-pack: start;
|
||||||
|
-webkit-justify-content: flex-start;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [layout][center-justified], html /deep/ [layout][center-center] {
|
||||||
|
-ms-flex-pack: center;
|
||||||
|
-webkit-justify-content: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [layout][end-justified] {
|
||||||
|
-ms-flex-pack: end;
|
||||||
|
-webkit-justify-content: flex-end;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [layout][around-justified] {
|
||||||
|
-ms-flex-pack: distribute;
|
||||||
|
-webkit-justify-content: space-around;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [layout][justified] {
|
||||||
|
-ms-flex-pack: justify;
|
||||||
|
-webkit-justify-content: space-between;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* self alignment */
|
||||||
|
|
||||||
|
html /deep/ [self-start] {
|
||||||
|
-ms-align-self: flex-start;
|
||||||
|
-webkit-align-self: flex-start;
|
||||||
|
align-self: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [self-center] {
|
||||||
|
-ms-align-self: center;
|
||||||
|
-webkit-align-self: center;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [self-end] {
|
||||||
|
-ms-align-self: flex-end;
|
||||||
|
-webkit-align-self: flex-end;
|
||||||
|
align-self: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [self-stretch] {
|
||||||
|
-ms-align-self: stretch;
|
||||||
|
-webkit-align-self: stretch;
|
||||||
|
align-self: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
Other Layout
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
html /deep/ [block] {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ie support for hidden */
|
||||||
|
html /deep/ [hidden] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [relative] {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
html /deep/ [fit] {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body[fullbleed] {
|
||||||
|
margin: 0;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
Other
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
html /deep/ [segment], html /deep/ segment {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-ms-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 1em 0.5em;
|
||||||
|
padding: 1em;
|
||||||
|
background-color: white;
|
||||||
|
-webkit-box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.1);
|
||||||
|
box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.1);
|
||||||
|
border-radius: 5px 5px 5px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|