I'm getting this error <[hCaptcha] render: invalid container 'null'.> on opera developer console.
I replaced my site key and it returned invalid container null.
Here is my source code.
<html>
<head>
<script src="https://hcaptcha.com/1/api.js?onload=yourFunction&render=explicit" async defer></script>
<script type="text/javascript">
var yourFunction = function () {
console.log('hCaptcha is ready.');
var widgetID = hcaptcha.render('captcha-1', { sitekey: 'MY_SITE_KEY' });
};
</script>
</head>
<body>
<div class="h-captcha" data-sitekey="MY_SITE_KEY" data-theme="dark"></div>
</body>
</html>
When render is called implicitly, the default containerId is h-captcha, as defined in the class of the target div.
When you call hcaptcha.render() explicitly, the first parameter is the containerId.
Due to this behavior, your problem can be resolved by either changing your first parameter of your render() call to h-captcha rather than captcha-1, or changing the class value to captcha-1.
Related
I am trying to provide a property to an iframe via its contentWindow and would like to do it in a synchronous manner.
I know I can access and set properties on the contentWindow of the iframe but the modification will occur after the iframe has loaded.
Parent
<body>
<script>
const frame = document.createElement('iframe')
document.body.appendChild(frame)
frame.src = 'frame.html'
frame.contentWindow.foobar = 'foobar'
</script>
</body>
iframe
<body>
<script>
console.log(window.foobar) // undefined
</script>
</body>
Is it possible to achieve or do I have to do this asynchronously by dispatching an event from the parent notifying the iframe that the property has been set?
I was able to find a solution to this. My goal was to create a "mock console" where any calls to console.log in the iframe document would be intercepted by the parent window. The problem was similar to OP's in that even though I overrode frame.contentWindow.console, it seemed to get re-set when the window loaded.
I'm not sure how exactly I solved it (I tried copying the replit previewer, luckily they had sourcemaps enabled), but nonetheless here is a plunkr showing a working example:
https://plnkr.co/edit/OLQ0wm8sZVUlMT0p?open=lib%2Fscript.js
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<p>Preview frame</p>
<div id="userCodePreviewWrapper"></div>
<p>Mock Console</p>
<div id="mockConsole"></div>
<script>
let contentWindow;
const consoleDiv = document.querySelector('#mockConsole');
function createConsole(frame) {
// Override the console object in the frame
contentWindow = frame.contentWindow;
frame.contentWindow.__nativeConsole = frame.contentWindow.console;
frame.contentWindow.console = {
log: function(msg) {
console.log("Logging console message", msg);
consoleDiv.innerHTML += `<p>${msg}</p>`;
}
}
}
document.addEventListener('DOMContentLoaded', () => {
const previewFrameDiv = document.querySelector('#userCodePreviewWrapper');
const previewFrame = document.createElement('iframe');
previewFrame.src = 'user-code.html';
previewFrame.setAttribute('id', 'userCodePreview');
previewFrame.setAttribute(
'sandbox',
'allow-forms allow-pointer-lock allow-popups ' +
'allow-same-origin allow-scripts allow-modals',
);
previewFrame.setAttribute('frameborder', 0);
previewFrameDiv.appendChild(previewFrame);
createConsole(previewFrame);
});
</script>
</body>
</html>
Am working on a HTML/JS Mediator that filters a data_model when a user enters text to a field. Have used window.onload = init, and spent four hours trying to find why 'this' in the browser makes it print the calling object, and thus I can't get a class instance to refer to itself using 'this'
console.log(this.text_field)
in setup_list_view() works fine, seemingly because it's within the constructors scope. Running it outside the constructor, as per below, gives:
Cannot set property 'innerHTML' of undefined at HTMLInputElement.handle_text_field_changed
...
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
function init() {
var text_field = document.getElementById("text-field");
var list_view = document.getElementById("list-view")
form_mediator = new FormMediator(text_field, list_view)
}
class FormMediator {
constructor(text_field, list_view) {
this.setup_text_field(text_field)
this.setup_list_view(list_view)
}
setup_text_field(text_field) {
this.text_field = text_field;
this.text_field.onchange = this.handle_text_field_changed
}
setup_list_view(list_view) {
this.data_model = ['England', 'Estonia', 'France', 'Germany']
this.list_view = list_view
this.list_view.innerHTML = this.data_model
}
does_string_start_with_text_field_text(text) {
return false;
return text.startsWith('E')
}
handle_text_field_changed(){
this.list_view.innerHTML = 'new content' //this.data_model.filter(this.does_string_start_with_text_field_text)
}
}
window.onload = init
</script>
<input id="text-field"><button>Search</button>
<span id="list-view"></span>
</body>
</html>
Any help much appreciated.
The problem in your code occurs in this line:
this.text_field.onchange = this.handle_text_field_changed
A method, by default, won't carry its original binding context if assigned to a variable or another object's property. You need to bind this handle_text_field_changed method first, this way:
this.text_field.onchange = this.handle_text_field_changed.bind(this)
I'm creating an HTML element using Polymer, and I want it to be able to work with an ES6 class I've written. Therefore, I need to import the class first and then register the element, which is what I do:
(function() {
System.import('/js/FoobarModel.js').then(function(m) {
window.FoobarModel = m.default;
window.FoobarItem = Polymer({
is: 'foobar-item',
properties: {
model: Object // instanceof FoobarModel === true
},
// ... methods using model and FoobarModel
});
});
})();
And it works well. But now I want to write a test HTML page to display my component with some dummy data:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="/bower_components/webcomponentsjs/webcomponents.js"></script>
<script src="/bower_components/system.js/dist/system.js"></script>
<script>
System.config({
map:{
traceur: '/bower_components/traceur/traceur.min.js'
}
});
</script>
<link rel="import" href="/html/foobar-item.html">
</head>
<body>
<script>
(function() {
var data = window.data = [
{
city: {
name: 'Foobar City'
},
date: new Date('2012-02-25')
}
];
var view;
for (var i = 0; i < data.length; i++) {
view = new FoobarItem();
view.model = data[i];
document.body.appendChild(view);
}
})();
</script>
</body>
</html>
Which isn't working for one simple reason: the code in the <script> tag is executed before Polymer registers the element.
Thus I'd like to know if there's a way to load the ES6 module synchronously using System.js or even better, if it's possible to listen to a JavaScript event for the element registration (something like PolymerElementsRegistered)?
I've tried the following without success:
window.addEventListener('HTMLImportsLoaded', ...)
window.addEventListener('WebComponentsReady', ...)
HTMLImports.whenReady(...)
In the app/scripts/app.js script from the polymer starter kit, they use auto-binding template and dom-change event
// Grab a reference to our auto-binding template
var app = document.querySelector('#app');
// Listen for template bound event to know when bindings
// have resolved and content has been stamped to the page
app.addEventListener('dom-change', function() {
console.log('Our app is ready to rock!');
});
Also check this thread gives alternatives to the polymer-ready event.
Is there a callback available in the Polymer({}) object which fires everytime the element is shown ?
ready is not suitable because it's called when the element is created on initial page load.
I need an event or callback every time the route changes and my element is displayed.
Why do I need this ? I have an element which is behaving differently if a certain request parameter is set. So I need to check on each load whether the parameter is set or not.
Edit:
I worked around my requirement by doing the stuff I need to be done on element display in my routing functions:
page("/app/list", function() {
document.querySelector("my-list").$.loadList.generateRequest();
app.route = "list";
});
In the meantime I came also accross app-route which as well has functionality to call methods on route or view changes.
You can read about it here:
https://www.polymer-project.org/1.0/toolbox/routing#take-action-on-route-changes
Here is a working example:
<!DOCTYPE html>
<html>
<head>
<script src="bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="bower_components/polymer/polymer.html" />
<link rel="import" href="bower_components/app-route/app-location.html" />
<link rel="import" href="bower_components/app-route/app-route.html" />
<link rel="import" href="bower_components/iron-pages/iron-pages.html" />
</head>
<body>
<container-element></container-element>
</body>
</html>
<dom-module id="container-element">
<template>
<app-location route="{{route}}" use-hash-as-path></app-location>
<app-route route="{{route}}" pattern=":view" data="{{routeData}}"></app-route>
Page 1 | Page 2
<iron-pages selected="[[routeData.view]]" attr-for-selected="name">
<div name="page1">This is Page 1.</div>
<x-element1 name="element1"></x-element1>
</iron-pages>
</template>
<script type="text/javascript">
Polymer({
is : "container-element",
observers : [ "_viewChanged(routeData.view)" ],
_viewChanged : function(view) {
if (view) {
if (view === "element1") {
document.querySelector("x-element1").test();
}
}
}
});
</script>
</dom-module>
<dom-module id="x-element1">
<template><p>This is Element 1.</p></template>
<script type="text/javascript">
Polymer({
is : "x-element1",
test : function() {
console.log("Callback of Element 1 called.");
}
});
</script>
</dom-module>
Maybe the attached callback is what you're looking for.
This lifecycle callback is called when an element is attached to the DOM and should therefore be the right choice. It is always called after the ready callback.
From the polymer docs:
https://www.polymer-project.org/1.0/docs/devguide/registering-elements.html#initialization-order
attached: function() {
this.async(function() {
// access sibling or parent elements here
});
}
index.html
<!DOCTYPE html>
<html>
<head>
<script src="https://google.github.io/traceur-compiler/bin/traceur.js"></script>
<script src="https://google.github.io/traceur-compiler/src/bootstrap.js"></script>
<script>
traceur.options.experimental = true;
</script>
<link rel="import" href="x-item.html">
</head>
<body>
<x-item></x-item>
</body>
</html>
and my web component:
x-item.html
<template id="itemtemplate">
<span>test</span>
</template>
<script type="module">
class Item extends HTMLElement {
constructor() {
let owner = document.currentScript.ownerDocument;
let template = owner.querySelector("#itemtemplate");
let clone = template.content.cloneNode(true);
let root = this.createShadowRoot();
root.appendChild(clone);
}
}
Item.prototype.createdCallback = Item.prototype.constructor;
Item = document.registerElement('x-item', Item);
</script>
and I get no error nor what I expect to be displayed, any idea if this should actually work?
Is this how one would extend an HTMLElement in ECMA6 syntax?
E: putting it altogether in one page solves the problem at least now I know its the right way to create a custom component, but the problem is having it in a separate file I think it has to do with how traceur handles <link rel="import" href="x-item.html"> I tried adding the type attribute to the import with no luck.
Traceur's inline processor does not appear to have support for finding <script> tags inside <link import>. All of traceur's code seems to access document directly, which results in traceur only looking at index.html and never seeing any <scripts> inside x-item.html. Here's a work around that works on Chrome. Change x-item.html to be:
<template id="itemtemplate">
<span>test</span>
</template>
<script type="module">
(function() {
let owner = document.currentScript.ownerDocument;
class Item extends HTMLElement {
constructor() {
// At the point where the constructor is executed, the code
// is not inside a <script> tag, which results in currentScript
// being undefined. Define owner above at compile time.
//let owner = document.currentScript.ownerDocument;
let template = owner.querySelector("#itemtemplate");
let clone = template.content.cloneNode(true);
let root = this.createShadowRoot();
root.appendChild(clone);
}
}
Item.prototype.createdCallback = Item.prototype.constructor;
Item = document.registerElement('x-item', Item);
})();
</script>
<script>
// Boilerplate to get traceur to compile the ECMA6 scripts in this include.
// May be a better way to do this. Code based on:
// new traceur.WebPageTranscoder().selectAndProcessScripts
// We can't use that method as it accesses 'document' which gives the parent
// document, not this include document.
(function processInclude() {
var doc = document.currentScript.ownerDocument,
transcoder = new traceur.WebPageTranscoder(doc.URL),
selector = 'script[type="module"],script[type="text/traceur"]',
scripts = doc.querySelectorAll(selector);
if (scripts.length) {
transcoder.addFilesFromScriptElements(scripts, function() {
console.log("done processing");
});
}
})();
</script>
Another possible solution would be to pre-compile the ECMA6 into ECMA5 and include the ECMA5 only. This would avoid the problem of traceur not finding the <script> tags in the import and would remove the need for the boilerplate.