I am playing a video with mediaelement.js. Works fine but when I want to change the source of the video I get an error:
SCRIPT438: Object doesn't support property or method 'setSrc'
Anyone an idea how to fix this?
code:
function playVideo(source) {
var fileformat:string
player.pause();
if (Modernizr.video) {
fileformat = ".mp4";
} else {
fileformat = ".flv";
}
var sources = [
{ src: 'media/'+ source + fileformat }
];
player.setSrc(sources);
player.load();
player.play();
}
Related
I have a plugin for my ckeditor build which should convert pasted content with formulas,
separated by '(' ')', '$$' etc. into math-formulas from ckeditor5-math (https://github.com/isaul32/ckeditor5-math). I changed the AutoMath Plugin so that it supports text with the separators.
I have run into a problem where undoing (ctrl-z) the operation works fine for single-line content, but not for multiline content.
To reproduce the issue, I have built a similar plugin which does not require the math plugin. This plugin converts text enclosed by '&' to bold text.
To reproduce this issue with an editor instance it is required to have the cursor inside a word (not after or before the end of the text, I don't know why that doesn't work, if you know why, help is appreciated^^) and paste it from the clipboard. The content will inside the '&' will be marked bold, however if you undo this operation twice, an model-position-path-incorrect-format error will be thrown.
example to paste:
aa &bb& cc
dd
ee &ff& gg
Undoing the operation twice results in this error:
Uncaught CKEditorError: model-position-path-incorrect-format {"path":[]}
Read more: https://ckeditor.com/docs/ckeditor5/latest/support/error-codes.html#error-model-position-path-incorrect-form
Unfortunately, I haven't found a way to fix this issue, and have not found a similar issue.
I know it has to do with the batches that are operated, and that maybe the position parent has to do something with it, that I should cache the position of the parent. However, I do not know how.
Below my code for an example to reproduce:
import Plugin from '#ckeditor/ckeditor5-core/src/plugin';
import Undo from '#ckeditor/ckeditor5-undo/src/undo';
import LiveRange from '#ckeditor/ckeditor5-engine/src/model/liverange';
import LivePosition from '#ckeditor/ckeditor5-engine/src/model/liveposition';
import global from '#ckeditor/ckeditor5-utils/src/dom/global';
export default class Test extends Plugin {
static get requires() {
return [Undo];
}
static get pluginName() {
return 'Test';
}
constructor(editor) {
super(editor);
this._timeoutId = null;
this._positionToInsert = null;
}
init() {
const editor = this.editor;
const modelDocument = editor.model.document;
const view = editor.editing.view;
//change < Clipboard > to < 'ClipboardPipeline' > because in version upgrade from 26 to 27
//the usage of this call changed
this.listenTo(editor.plugins.get('ClipboardPipeline'), 'inputTransformation', (evt, data) => {
const firstRange = modelDocument.selection.getFirstRange();
const leftLivePosition = LivePosition.fromPosition(firstRange.start);
leftLivePosition.stickiness = 'toPrevious';
const rightLivePosition = LivePosition.fromPosition(firstRange.end);
rightLivePosition.stickiness = 'toNext';
modelDocument.once('change:data', () => {
this._boldBetweenPositions(leftLivePosition, rightLivePosition);
leftLivePosition.detach();
rightLivePosition.detach();
}, {priority: 'high'});
});
editor.commands.get('undo').on('execute', () => {
if (this._timeoutId) {
global.window.clearTimeout(this._timeoutId);
this._timeoutId = null;
}
}, {priority: 'high'});
}
_boldBetweenPositions(leftPosition, rightPosition) {
const editor = this.editor;
const equationRange = new LiveRange(leftPosition, rightPosition);
// With timeout user can undo conversation if wants to use plain text
this._timeoutId = global.window.setTimeout(() => {
this._timeoutId = null;
let walker = equationRange.getWalker({ignoreElementEnd: true});
let nodeArray = [];
for (const node of walker) { // remember nodes, because when they are changed model-textproxy-wrong-length error occurs
nodeArray.push(node);
}
editor.model.change(writer => {
for (let node of nodeArray) {
let text = node.item.data;
if (node.item.is('$textProxy') && text !== undefined && text.match(/&/g)) {
let finishedFormulas = this._split(text);
const realRange = writer.createRange(node.previousPosition, node.nextPosition);
writer.remove(realRange);
for (let i = finishedFormulas.length - 1; i >= 0; i--) {
if (i % 2 === 0) {
writer.insertText(finishedFormulas[i], node.previousPosition);
} else {
writer.insertText(finishedFormulas[i], {bold: true}, node.previousPosition);
}
}
}
}
});
}, 100);
}
_split(text) {
let mathFormsAndText = text.split(/(&)/g);
let mathTextArray = [];
for (let i = 0; i < mathFormsAndText.length; i++) {
if (i % 4 === 0) {
mathTextArray.push(mathFormsAndText[i]);
} else if (i % 2 === 0) {
mathTextArray.push(mathFormsAndText[i]);
}
}
return mathTextArray;
}
}
Let me know if I can clarify anything.
I have main.qml and dynamic.qml files that i want to load dynamic.qml on main.qml using Loader {}.
Content of dynamic.qml file is dynamic and another program may change its content and overwrite it.
So i wrote some C++ code for detecting changes on file and fires Signal.
My problem is that I don't know how can i force Loader to reload file.
This is my current work:
MainController {
id: mainController
onInstallationHelpChanged: {
helpLoader.source = "";
helpLoader.source = "../dynamic.qml";
}
}
Loader {
id: helpLoader
anchors.fill: parent
anchors.margins: 60
source: "../dynamic.qml"
}
I think that QML Engine caches dynamic.qml file. So whenever I want to reload Loader, it shows old content. Any suggestion?
You need to call trimComponentCache() on QQmlEngine after you have set the Loaders source property to an empty string. In other words:
helpLoader.source = "";
// call trimComponentCache() here!!!
helpLoader.source = "../dynamic.qml";
In order to do that, you'll need to expose some C++ object to QML which has a reference to your QQmlEngine (lots of examples in Qt and on StackOverflow to help with that).
trimComponentCache tells QML to forget about all the components it's not current using and does just what you want.
Update - explaining in a bit more detail:
For example, somewhere you define a class that takes a pointer to your QQmlEngine and exposes the trimComponentCache method:
class ComponentCacheManager : public QObject {
Q_OBJECT
public:
ComponentCacheManager(QQmlEngine *engine) : engine(engine) { }
Q_INVOKABLE void trim() { engine->trimComponentCache(); }
private:
QQmlEngine *engine;
};
Then when you create your QQuickView, bind one of the above as a context property:
QQuickView *view = new QQuickView(...);
...
view->rootContext()->setContextProperty(QStringLiteral("componentCache", new ComponentCacheManager(view->engine());
Then in your QML you can do something like:
helpLoader.source = "";
componentCache.trim();
helpLoader.source = "../dynamic.qml";
I was hoping for a pure QML solution. I noticed that loader.source is a url (file:///) and remembered how with HTML, you can avoid HTTP caching using ?t=Date.now() in your requests. Tried adding ?t=1234 to the end of loader.source, and sure enough, it works.
import QtQuick 2.0
Item {
Loader {
id: loader
anchors.fill: parent
property string filename: "User.qml"
source: filename
function reload() {
source = filename + "?t=" + Date.now()
}
}
Timer {
id: reloadTimer
interval: 2000
repeat: true
running: true
onTriggered: {
loader.reload();
}
}
}
I also wrote another example that will check for changes in the file contents before triggering a reload using an XMLHttpRequest.
import QtQuick 2.0
Item {
Loader {
id: loader
anchors.fill: parent
property string filename: "AppletUser.qml"
property string fileContents: ""
source: ""
function reload() {
source = filename + "?t=" + Date.now()
}
function checkForChange() {
var req = new XMLHttpRequest();
req.onreadystatechange = function() {
if (req.readyState === 4) {
if (loader.fileContents != req.responseText) {
loader.fileContents = req.responseText;
loader.reload();
}
}
}
req.open("GET", loader.filename, true);
req.send();
}
onLoaded: {
console.log(source)
}
Timer {
id: reloadTimer
interval: 2000
repeat: true
running: true
onTriggered: loader.checkForChange()
}
Component.onCompleted: {
loader.checkForChange()
}
}
}
I browsed though many "unexpected token", "illegal" etc. topics, one helped me by checking for invisible characters and copying the script to jslint throwed me some missed brackets error, but there are still one problem with this line:
JS:
document.getElementById('pois').innerHTML =('<p><label><input type="checkbox" id="01" onclick="toggleGroup("01")" CHECKED/></label>01</p>');
The pois div is located in the html file.
Alternatively, how would I write the above line with jQuery, as the inline JS is not considered correct? The below function doesn't work as I'd like:
$("#01").click(function() {
toggleGroup();
});
The corresponding function:
var markerGroups = { "01": [], "02": [] , "03": [] , "04": [] };
function toggleGroup(id_category) {
for (var i = 0; i < markerGroups[id_category].length; i++) {
var marker = markerGroups[id_category][i];
if (marker.getMap()) {
marker.setMap(null);
} else {
marker.setMap(map);
}
}
}
Perhaps you need to change onclick to onchange? This will capture the tick box change event. I'm not too sure what the toggleGroup function is doing but this might help.
The error raised because you have missed one bracket } on end of your function
function toggleGroup(id_category) {
for (var i = 0; i < markerGroups[id_category].length; i++) {
var marker = markerGroups[id_category][i];
if (marker.getMap()) {
marker.setMap(null);
} else {
marker.setMap(map);
}
}
} //<== missing one
http://jsfiddle.net/QF9sN/5/
Can we do copy(Ctrl+C) and paste(Ctrl+V) the image from User system(desktop/any folder) to canvas using fabric.js. I have seen the copy and paste program inside the canvas, I have found this Example while searching google but didnt find any relevant example for desktop to canvas. Here is the snippet for copy and paste
function onKeyDownHandler(event) {
//event.preventDefault();
var key;
if(window.event){
key = window.event.keyCode;
}
else{
key = event.keyCode;
}
switch(key){
//////////////
// Shortcuts
//////////////
// Copy (Ctrl+C)
case 67: // Ctrl+C
if(ableToShortcut()){
if(event.ctrlKey){
event.preventDefault();
copy();
}
}
break;
// Paste (Ctrl+V)
case 86: // Ctrl+V
if(ableToShortcut()){
if(event.ctrlKey){
event.preventDefault();
paste();
}
}
break;
default:
// TODO
break;
}
}
function ableToShortcut(){
/*
TODO check all cases for this
if($("textarea").is(":focus")){
return false;
}
if($(":text").is(":focus")){
return false;
}
*/
return true;
}
function copy(){
if(canvas.getActiveGroup()){
for(var i in canvas.getActiveGroup().objects){
var object = fabric.util.object.clone(canvas.getActiveGroup().objects[i]);
object.set("top", object.top+5);
object.set("left", object.left+5);
copiedObjects[i] = object;
}
}
else if(canvas.getActiveObject()){
var object = fabric.util.object.clone(canvas.getActiveObject());
object.set("top", object.top+5);
object.set("left", object.left+5);
copiedObject = object;
copiedObjects = new Array();
}
}
function paste(){
if(copiedObjects.length > 0){
for(var i in copiedObjects){
canvas.add(copiedObjects[i]);
}
}
else if(copiedObject){
canvas.add(copiedObject);
}
canvas.renderAll();
}
Is it possible to do actually I have heard dat it's may not possible.Can anyone guide me how to do please.
If you're targeting modern browsers you can combine 2 new (but widely adopted) html5 features to accomplish your task:
You can create a dropzone on your page using the dragover and drop events.
Then you can use the FileReader API to read the image files into an image object.
Then it's back to FabricJS to load the image as usual.
Here's a tutorial describing how to do the hard bits (#1,#2): http://www.html5rocks.com/en/tutorials/file/dndfiles/
[ Added code that SOMETIMES allows cut/paste of image files ]
Most modern browsers support binding the “paste” event.
// listen for the paste event
window.addEventListener("paste",pasteImage);
But...!!
Support for non-text mime types (ie “image”) is scarce. Chrome seems to support it “off-and-on”.
…And browsers are constantly revising their cut/paste capabilities because of security concerns.
Here is code that sometimes works in Chrome.
// listen for the paste event
window.addEventListener("paste",pasteImage);
function pasteImage(event) {
// get the raw clipboardData
var cbData=event.clipboardData;
for(var i=0;i<cbData.items.length;i++){
// get the clipboard item
var cbDataItem = cbData.items[i];
var type = cbDataItem.type;
// warning: most browsers don't support image data type
if (type.indexOf("image")!=-1) {
// grab the imageData (as a blob)
var imageData = cbDataItem.getAsFile();
// format the imageData into a URL
var imageURL=window.webkitURL.createObjectURL(imageData);
// We've got an imageURL, add code to use it as needed
// the imageURL can be used as src for an Image object
}
}
}
I've read countless threads and tried implementing many different suggestions, but haven't had any luck.
first:
function ajaxRequest() {
try {
var request = new XMLHttpRequest();
}
catch(e1) {
try {
var request = new ActiveXObject("Msxml2.HTMLHTTP");
}
catch(e2) {
try {
var request = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e3) {
var request = false;
}
}
}
return request;
}
It looks like IE is successfully using XMLHttpRequest. As far as I can tell, it's loading the XML fine, but Xpath is another story:
function XMLPath(doc, path) {
try {
return doc.evaluate(path, doc, null, XPathResult.STRING_TYPE, null).stringValue;
} catch (e) {
try {
doc.setProperty("SelectionLanguage", "XPath");
return doc.selectNodes(path);
}
catch(e2) {
alert(e2);
}
}
}
Basically, what must I change in my catch statement to make it work with IE? What's also interesting is that it never alerts an e2 error, meaning it's not actually throwing an error. Totally confused.
Thanks.
Try return doc.selectSingleNode(path).text; for IE, that is the closest you can get for accessing the string value of the node found by your path.