Merge branch 'stable-3.3'
* stable-3.3:
Stop propagation for all keys but exempt the save button
Change-Id: I57b4d93937458ce68a235d5867fd8fe5efdf92da
diff --git a/BUILD b/BUILD
index 8b11bd5..7e2c5c6 100644
--- a/BUILD
+++ b/BUILD
@@ -15,11 +15,14 @@
genrule2(
name = "cm-static",
- srcs = [":codemirror_editor"],
+ srcs = [
+ ":codemirror-element",
+ ":codemirror_editor",
+ ],
outs = ["cm-static.jar"],
cmd = " && ".join([
"mkdir $$TMP/static",
- "cp -r $(locations :codemirror_editor) $$TMP/static",
+ "cp $(SRCS) $$TMP/static",
"cd $$TMP",
"zip -Drq $$ROOT/$@ -g .",
]),
@@ -40,7 +43,4 @@
polygerrit_plugin(
name = "codemirror_editor",
app = "gr-editor/gr-editor.js",
- assets = [
- ":codemirror-element",
- ],
)
diff --git a/README.md b/README.md
index c85c098..96d3063 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@
You will need `polymer-bridges` which is a submodule you can clone from: https://gerrit-review.googlesource.com/admin/repos/polymer-bridges
-As polymer 3 no longer support `Polymer.importHref` anymore, Gerrit still supports through a custom implementation, the implementation is copied here for testing purpose (`test/import-href.js`).
+As polymer 3 no longer support `Polymer.importHref` anymore, this plugin still supports it through a custom implementation in `gr-editor.js`.
## Test plugin on Gerrit
@@ -28,4 +28,4 @@
If your plugin is already enabled, then you can block it and then inject the compiled local verison.
-See more about how to use dev helper extension to help you test here: https://gerrit.googlesource.com/gerrit-fe-dev-helper/+/master
\ No newline at end of file
+See more about how to use dev helper extension to help you test here: https://gerrit.googlesource.com/gerrit-fe-dev-helper/+/master
diff --git a/bower.json b/bower.json
index 6de966f..f932829 100644
--- a/bower.json
+++ b/bower.json
@@ -5,7 +5,7 @@
],
"license": "http://www.apache.org/licenses/LICENSE-2.0",
"dependencies": {
- "codemirror-minified": "^5.50.2"
+ "codemirror-minified": "^5.59.1"
},
"devDependencies": {
"es6-promise": "^3.3.1",
diff --git a/gr-editor/gr-editor.js b/gr-editor/gr-editor.js
index d7297ad..c88e2a8 100644
--- a/gr-editor/gr-editor.js
+++ b/gr-editor/gr-editor.js
@@ -15,6 +15,86 @@
* limitations under the License.
*/
+// Run a callback when HTMLImports are ready or immediately if
+// this api is not available.
+function whenImportsReady(cb) {
+ if (window.HTMLImports) {
+ HTMLImports.whenReady(cb);
+ } else {
+ cb();
+ }
+}
+
+/**
+ * Convenience method for importing an HTML document imperatively. Mostly copied
+ * from polymer/lib/utils/import-href.html.
+ *
+ * This method creates a new `<link rel="import">` element with
+ * the provided URL and appends it to the document to start loading.
+ * In the `onload` callback, the `import` property of the `link`
+ * element will contain the imported document contents.
+ *
+ * @param {string} href URL to document to load.
+ * @param {?function(!Event):void=} onload Callback to notify when an import successfully
+ * loaded.
+ * @param {?function(!ErrorEvent):void=} onerror Callback to notify when an import
+ * unsuccessfully loaded.
+ */
+function importHref(href, onload, onerror) {
+ let link =
+ /** @type {HTMLLinkElement} */
+ (document.head.querySelector('link[href="' + href + '"][import-href]'));
+ if (!link) {
+ link = /** @type {HTMLLinkElement} */ (document.createElement('link'));
+ link.setAttribute('rel', 'import');
+ link.setAttribute('href', href);
+ link.setAttribute('import-href', '');
+ }
+ // NOTE: the link may now be in 3 states: (1) pending insertion,
+ // (2) inflight, (3) already loaded. In each case, we need to add
+ // event listeners to process callbacks.
+ const cleanup = function() {
+ link.removeEventListener('load', loadListener);
+ link.removeEventListener('error', errorListener);
+ };
+ const loadListener = function(event) {
+ cleanup();
+ // In case of a successful load, cache the load event on the link so
+ // that it can be used to short-circuit this method in the future when
+ // it is called with the same href param.
+ link.__dynamicImportLoaded = true;
+ if (onload) {
+ whenImportsReady(() => {
+ onload(event);
+ });
+ }
+ };
+ const errorListener = function(event) {
+ cleanup();
+ // In case of an error, remove the link from the document so that it
+ // will be automatically created again the next time `importHref` is
+ // called.
+ if (link.parentNode) {
+ link.parentNode.removeChild(link);
+ }
+ if (onerror) {
+ whenImportsReady(() => {
+ onerror(event);
+ });
+ }
+ };
+ link.addEventListener('load', loadListener);
+ link.addEventListener('error', errorListener);
+ if (link.parentNode == null) {
+ document.head.appendChild(link);
+ // if the link already loaded, dispatch a fake load event
+ // so that listeners are called and get a proper event argument.
+ } else if (link.__dynamicImportLoaded) {
+ link.dispatchEvent(new Event('load'));
+ }
+ return link;
+}
+
// we need to be on codemirror 5.33.0+ to get the support for
// text/x-php in CodeMirror.findModeByMIME
const LANGUAGE_MAP = {
@@ -87,7 +167,7 @@
const codemirrorElementFile = '/static/codemirror-element.html';
const url = this.plugin.url(codemirrorElementFile);
return new Promise((resolve, reject) => {
- Polymer.importHref(url, resolve, reject);
+ importHref(url, resolve, reject);
});
}
@@ -159,9 +239,8 @@
customElements.define(GrEditor.is, GrEditor);
-// Install the plugin
if (window.Gerrit) {
Gerrit.install(plugin => {
plugin.registerCustomComponent('editor', 'gr-editor', {replace: true});
});
-}
\ No newline at end of file
+}
diff --git a/gr-editor/gr-editor_test.html b/gr-editor/gr-editor_test.html
index 586d703..fcbcb5f 100644
--- a/gr-editor/gr-editor_test.html
+++ b/gr-editor/gr-editor_test.html
@@ -31,6 +31,7 @@
<script type="module">
import '../test/common-test-setup.js';
import './gr-editor.js';
+import {importHref} from './gr-editor.js';
suite('gr-editor tests', () => {
let element;
let sandbox;
@@ -41,7 +42,7 @@
stub('gr-editor', {
_importCodeMirror() {
return new Promise((resolve, reject) => {
- Polymer.importHref('./codemirror-element.html', resolve, reject);
+ importHref('./codemirror-element.html', resolve, reject);
});
},
});
diff --git a/java/com/googlesource/gerrit/plugins/codemirror/CodemirrorModule.java b/java/com/googlesource/gerrit/plugins/codemirror/CodemirrorModule.java
index 0bba486..c1ccee3 100644
--- a/java/com/googlesource/gerrit/plugins/codemirror/CodemirrorModule.java
+++ b/java/com/googlesource/gerrit/plugins/codemirror/CodemirrorModule.java
@@ -23,6 +23,6 @@
@Override
protected void configure() {
DynamicSet.bind(binder(), WebUiPlugin.class)
- .toInstance(new JavaScriptPlugin("codemirror_editor.html"));
+ .toInstance(new JavaScriptPlugin("codemirror_editor.js"));
}
}
diff --git a/test/common-test-setup.js b/test/common-test-setup.js
index a0f1f1b..1158af4 100644
--- a/test/common-test-setup.js
+++ b/test/common-test-setup.js
@@ -57,6 +57,3 @@
import 'polymer-bridges/polymer/polymer-legacy_bridge.js';
import '@polymer/iron-test-helpers/iron-test-helpers.js';
-import {importHref} from './import-href.js';
-
-window.Polymer.importHref = importHref;
diff --git a/test/import-href.js b/test/import-href.js
deleted file mode 100644
index 80ae389..0000000
--- a/test/import-href.js
+++ /dev/null
@@ -1,109 +0,0 @@
-/**
- * @license
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// This file is a replacement for the
-// polymer-bridges/polymer/lib/utils/import-href.html file. The html
-// file contains code inside <script>...</script> and can't be imported
-// in es6 modules.
-
-// run a callback when HTMLImports are ready or immediately if
-// this api is not available.
-function whenImportsReady(cb) {
- if (window.HTMLImports) {
- HTMLImports.whenReady(cb);
- } else {
- cb();
- }
-}
-
-/**
- * Convenience method for importing an HTML document imperatively.
- *
- * This method creates a new `<link rel="import">` element with
- * the provided URL and appends it to the document to start loading.
- * In the `onload` callback, the `import` property of the `link`
- * element will contain the imported document contents.
- *
- * @memberof Polymer
- * @param {string} href URL to document to load.
- * @param {?function(!Event):void=} onload Callback to notify when an import successfully
- * loaded.
- * @param {?function(!ErrorEvent):void=} onerror Callback to notify when an import
- * unsuccessfully loaded.
- * @param {boolean=} optAsync True if the import should be loaded `async`.
- * Defaults to `false`.
- * @return {!HTMLLinkElement} The link element for the URL to be loaded.
- */
-export function importHref(href, onload, onerror, optAsync) {
- let link =
- /** @type {HTMLLinkElement} */
- (document.head.querySelector('link[href="' + href + '"][import-href]'));
- if (!link) {
- link = /** @type {HTMLLinkElement} */ (document.createElement("link"));
- link.rel = "import";
- link.href = href;
- link.setAttribute("import-href", "");
- }
- // always ensure link has `async` attribute if user specified one,
- // even if it was previously not async. This is considered less confusing.
- if (optAsync) {
- link.setAttribute("async", "");
- }
- // NOTE: the link may now be in 3 states: (1) pending insertion,
- // (2) inflight, (3) already loaded. In each case, we need to add
- // event listeners to process callbacks.
- const cleanup = function () {
- link.removeEventListener("load", loadListener);
- link.removeEventListener("error", errorListener);
- };
- const loadListener = function (event) {
- cleanup();
- // In case of a successful load, cache the load event on the link so
- // that it can be used to short-circuit this method in the future when
- // it is called with the same href param.
- link.__dynamicImportLoaded = true;
- if (onload) {
- whenImportsReady(() => {
- onload(event);
- });
- }
- };
- const errorListener = function (event) {
- cleanup();
- // In case of an error, remove the link from the document so that it
- // will be automatically created again the next time `importHref` is
- // called.
- if (link.parentNode) {
- link.parentNode.removeChild(link);
- }
- if (onerror) {
- whenImportsReady(() => {
- onerror(event);
- });
- }
- };
- link.addEventListener("load", loadListener);
- link.addEventListener("error", errorListener);
- if (link.parentNode == null) {
- document.head.appendChild(link);
- // if the link already loaded, dispatch a fake load event
- // so that listeners are called and get a proper event argument.
- } else if (link.__dynamicImportLoaded) {
- link.dispatchEvent(new Event("load"));
- }
- return link;
-}