Delete DEPRECATED directory

This commit is contained in:
Teddy-1024
2024-09-17 09:16:31 +01:00
committed by GitHub
parent fa7f1b35ee
commit 7c3f4c9431
15 changed files with 0 additions and 2033 deletions

View File

@@ -1,126 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image Annotation Control</title>
<style>
.image-annotator {
width: 800px;
margin: 0 auto;
padding: 20px;
border: 1px solid #ccc;
}
.canvas-container {
position: relative;
margin-bottom: 10px;
}
#imageCanvas {
border: 1px solid #000;
}
.toolbar {
margin-bottom: 10px;
}
.toolbar button {
margin-right: 5px;
}
</style>
</head>
<body>
<div class="image-annotator">
<input type="file" id="imageUpload" accept="image/png">
<div class="canvas-container">
<canvas id="imageCanvas"></canvas>
</div>
<div class="toolbar">
<button id="addArrow">Add Arrow</button>
<button id="addTextbox">Add Textbox</button>
<button id="eraseElement">Erase Element</button>
</div>
<button id="saveButton">Save</button>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.5.0/fabric.min.js"></script>
<script>
(function($) {
$.fn.imageAnnotator = function(options) {
return this.each(function() {
const $container = $(this);
const $imageUpload = $container.find('#imageUpload');
const $canvas = $container.find('#imageCanvas');
const $addArrow = $container.find('#addArrow');
const $addTextbox = $container.find('#addTextbox');
const $eraseElement = $container.find('#eraseElement');
const $saveButton = $container.find('#saveButton');
let canvas = new fabric.Canvas('imageCanvas', {
width: 800,
height: 600
});
$imageUpload.on('change', function(e) {
const file = e.target.files[0];
const reader = new FileReader();
reader.onload = function(f) {
fabric.Image.fromURL(f.target.result, function(img) {
canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas), {
scaleX: canvas.width / img.width,
scaleY: canvas.height / img.height
});
});
};
reader.readAsDataURL(file);
});
$addArrow.on('click', function() {
const arrow = new fabric.Path('M 0 0 L 200 100', {
fill: 'red',
stroke: 'red',
strokeWidth: 2,
left: 100,
top: 100
});
canvas.add(arrow);
});
$addTextbox.on('click', function() {
const textbox = new fabric.Textbox('Enter text', {
left: 100,
top: 100,
width: 150,
fontSize: 20
});
canvas.add(textbox);
});
$eraseElement.on('click', function() {
const activeObject = canvas.getActiveObject();
if (activeObject) {
canvas.remove(activeObject);
}
});
$saveButton.on('click', function() {
if (confirm("Please ensure there is no sensitive information or PII in your annotations. Do you want to proceed?")) {
const dataURL = canvas.toDataURL({
format: 'png',
quality: 1
});
console.log(dataURL); // In a real application, you would send this to your server
alert("Image saved as Base64 string. Check the console for the output.");
}
});
});
};
}(jQuery));
// Initialize the plugin
$(document).ready(function() {
$('.image-annotator').imageAnnotator();
});
</script>
</body>
</html>

View File

@@ -1,121 +0,0 @@
(function($) {
$.fn.screenshotExporter = function(options) {
var settings = $.extend({
filename: 'screenshot.png',
excludeSelector: null
}, options);
return this.each(function() {
var $button = $(this);
$button.on('click', function() {
takeScreenshot();
});
function takeScreenshot() {
// Hide the button temporarily
$button.hide();
// Find the maximum z-index in the document
var maxZIndex = Math.max(
...Array.from(document.querySelectorAll('body *'))
.map(a => parseFloat(window.getComputedStyle(a).zIndex))
.filter(a => !isNaN(a))
);
// Create a wrapper div
var $wrapper = $('<div>')
.css({
position: 'absolute',
left: 0,
top: 0,
width: '100%',
height: '100%',
zIndex: maxZIndex + 1,
pointerEvents: 'none'
})
.appendTo('body');
// Move all fixed and absolute positioned elements into the wrapper
$('body *').each(function() {
var $el = $(this);
var position = $el.css('position');
if (position === 'fixed' || position === 'absolute') {
var offset = $el.offset();
$el.data('original-position', {
parent: $el.parent(),
nextSibling: $el.next(),
position: position,
top: $el.css('top'),
left: $el.css('left'),
zIndex: $el.css('z-index')
});
$el.appendTo($wrapper)
.css({
position: 'absolute',
top: offset.top,
left: offset.left,
zIndex: position === 'fixed' ? (parseFloat($el.css('z-index')) || 0) + maxZIndex : $el.css('z-index')
});
}
});
// Use html2canvas to capture the screenshot
html2canvas(document.body, {
ignoreElements: function(element) {
// Exclude the button and any elements matching the excludeSelector
return element === $button[0] ||
(settings.excludeSelector && $(element).is(settings.excludeSelector));
},
windowWidth: document.documentElement.scrollWidth,
windowHeight: document.documentElement.scrollHeight
}).then(function(canvas) {
// Convert canvas to blob
canvas.toBlob(function(blob) {
// Create a temporary URL for the blob
var url = URL.createObjectURL(blob);
// Create a temporary anchor element
var a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = settings.filename;
// Append the anchor to the body, click it, and remove it
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
// Revoke the blob URL
URL.revokeObjectURL(url);
// Restore the original positions of moved elements
$wrapper.children().each(function() {
var $el = $(this);
var originalPosition = $el.data('original-position');
if (originalPosition) {
if (originalPosition.nextSibling.length) {
$el.insertBefore(originalPosition.nextSibling);
} else {
$el.appendTo(originalPosition.parent);
}
$el.css({
position: originalPosition.position,
top: originalPosition.top,
left: originalPosition.left,
zIndex: originalPosition.zIndex
});
}
});
// Remove the wrapper
$wrapper.remove();
// Show the button again
$button.show();
});
});
}
});
};
}(jQuery));

View File

@@ -1,183 +0,0 @@
var isEraseMode = false;
var activeSelection = null;
function hookupPageDisplayPng() {
const canvas = new fabric.Canvas('canvas');
const symbolSelect = document.getElementById('symbolSelect');
const colorPicker = document.getElementById('colorPicker');
const symbols = ['Orange Arrow.png'];
// Populate symbol select
symbols.forEach(symbol => {
const option = document.createElement('option');
option.value = symbol;
option.textContent = symbol.replace('.png', '');
symbolSelect.appendChild(option);
});
// Image upload
document.getElementById('imageUpload').addEventListener('change', function(e) {
const file = e.target.files[0];
const reader = new FileReader();
reader.onload = function(f) {
fabric.Image.fromURL(f.target.result, function(img) {
canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas), {
scaleX: canvas.width / img.width,
scaleY: canvas.height / img.height
});
});
};
reader.readAsDataURL(file);
});
// Add arrow
document.getElementById('addArrow').addEventListener('click', function() {
const arrow = new fabric.Path('M 0 0 L 200 100', {
fill: colorPicker.value,
stroke: colorPicker.value,
strokeWidth: 2,
left: 100,
top: 100
});
canvas.add(arrow);
});
// Add textbox
document.getElementById('addTextbox').addEventListener('click', function() {
const textbox = new fabric.Textbox('Type here', {
left: 100,
top: 100,
width: 150,
fontSize: 20,
fill: colorPicker.value
});
canvas.add(textbox);
});
// Add symbol
symbolSelect.addEventListener('change', function() {
if (this.value) {
fabric.Image.fromURL(`symbols/${this.value}`, function(img) {
img.set({
left: 100,
top: 100,
scaleX: 0.5,
scaleY: 0.5
});
canvas.add(img);
});
this.value = ''; // Reset select
}
});
// Color change for selected object
colorPicker.addEventListener('change', function() {
const activeObject = canvas.getActiveObject();
if (activeObject) {
if (activeObject.type === 'textbox') {
activeObject.set('fill', this.value);
} else {
activeObject.set('fill', this.value);
activeObject.set('stroke', this.value);
}
canvas.renderAll();
}
});
// Erase mode
document.getElementById('eraseMode').addEventListener('click', function() {
isEraseMode = !isEraseMode;
this.textContent = isEraseMode ? 'Exit Erase Mode' : 'Erase Mode';
if (isEraseMode) {
// Delete any pre-selected elements when entering erase mode
deleteSelectedObjects(canvas);
// Disable selection and drawing
canvas.selection = false;
canvas.isDrawingMode = false;
// Change cursor to indicate erase mode
canvas.defaultCursor = 'crosshair';
canvas.hoverCursor = 'crosshair';
} else {
// Re-enable selection when exiting erase mode
canvas.selection = true;
// Reset cursors
canvas.defaultCursor = 'default';
canvas.hoverCursor = 'move';
}
});
// Object selection in erase mode
canvas.on('selection:created', function(options) {
if (isEraseMode) {
deleteSelectedObjects(canvas);
}
});
canvas.on('mouse:down', function(options) {
if (isEraseMode && options.target) {
canvas.remove(options.target);
canvas.requestRenderAll();
}
});
// Prevent dragging in erase mode
canvas.on('object:moving', function(options) {
if (isEraseMode) {
options.target.setCoords();
canvas.remove(options.target);
canvas.requestRenderAll();
}
});
// Save image
document.getElementById('saveImage').addEventListener('click', function() {
if (confirm("Please ensure there is no sensitive information or PII in your annotations. Do you want to proceed with saving?")) {
const dataURL = canvas.toDataURL({
format: 'png',
quality: 1
});
console.log("Base64 string:", dataURL);
// Here you would typically send this dataURL to your server or database
alert("Image saved as Base64 string. Check the console for the output.");
}
});
/*
// Object selection
canvas.on('selection:created', function(options) {
if (isEraseMode && options.target) {
canvas.remove(options.target);
} else if (options.target) {
if (options.target.type === 'textbox') {
colorPicker.value = options.target.fill;
} else {
colorPicker.value = options.target.stroke || options.target.fill;
}
}
});
*/
}
function deleteSelectedObjects(canvas) {
// const canvas = new fabric.Canvas('canvas');
const activeObject = canvas.getActiveObject();
if (activeObject) {
if (activeObject.type === 'activeSelection') {
// If it's a multi-selection, remove all selected objects
activeObject.forEachObject(function(obj) {
canvas.remove(obj);
});
canvas.discardActiveObject();
} else {
// If it's a single object, just remove it
canvas.remove(activeObject);
}
canvas.requestRenderAll();
}
}

View File

@@ -1,268 +0,0 @@
(function($) {
$.fn.annotatorPNG = function(options) {
var settings = $.extend({
heightCanvas: "600px",
widthCanvas: "800px",
}, options);
var flagToolbox = "annotator-png-toolbox";
var flagContainer = "annotator-png-container";
var flagContainerAnnotation = "annotator-png-container-annotation";
var flagUploadImage = "annotator-png-upload-image";
var flagAddArrow = "annotator-png-add-arrow";
var flagAddTextbox = "annotator-png-add-textbox";
var flagAddSymbol = "annotator-png-add-symbol";
var flagColourPicker = "annotator-png-colour-picker";
var flagEraseMode = "annotator-png-erase-mode";
var flagSaveImage = "annotator-png-save-image";
var flagCanvasAnnotation = "annotator-png-canvas-annotation";
var keyFabric = "fabric";
var keyIsEraseMode = "isEraseMode";
function getCanvas() {
let $annotatorPNG = $(document).find("." + flagAnnotatorPNG);
let $canvasAnnotation = $annotatorPNG.find("canvas." + flagCanvasAnnotation);
let canvas = $canvasAnnotation.data(keyFabric);
console.log("canvas: ", canvas);
return canvas;
}
function deleteSelectedObjects() {
let canvas = getCanvas();
const activeObject = canvas.getActiveObject();
if (activeObject) {
console.log("active object type:", activeObject.type);
if (activeObject.type === 'activeSelection') {
// If it's a multi-selection, remove all selected objects
activeObject.forEachObject(function(obj) {
canvas.remove(obj);
});
canvas.discardActiveObject();
} else {
// If it's a single object, just remove it
canvas.remove(activeObject);
}
canvas.requestRenderAll();
}
}
return this.each(function() {
var $annotatorPNG = $(this);
$annotatorPNG.data(keyIsEraseMode, false);
const symbols = ['Orange Arrow.png'];
// Make elements
var $toolbox = $('<div class="' + flagToolbox + ' ' + flagContainer + '"></div>');
var $inputUploadImage = $('<input type="file" class="' + flagUploadImage + '" accept="image/*">');
$toolbox.append($inputUploadImage);
var $buttonAddArrow = $('<button class="' + flagAddArrow + '">Add Arrow</button>');
$toolbox.append($buttonAddArrow);
var $buttonAddTextbox = $('<button class="' + flagAddTextbox + '">Add Textbox</button>');
$toolbox.append($buttonAddTextbox);
var $selectAddSymbol = $('<select class="' + flagAddSymbol + '"></select>');
$selectAddSymbol.append($("<option>", {
value: "",
text: "Select Symbol",
}));
symbols.forEach(symbol => {
$selectAddSymbol.append($("<option>", {
value: symbol,
text: symbol.replace('.png', ''),
}));
});
$toolbox.append($selectAddSymbol);
var $inputColourPicker = $('<input type="color" class="' + flagColourPicker + '">');
$toolbox.append($inputColourPicker);
var $buttonEraseMode = $('<button class="' + flagEraseMode + '">Erase Mode</button>');
$toolbox.append($buttonEraseMode);
var $buttonSaveImage = $('<button class="' + flagSaveImage + '">Save Image</button>');
$toolbox.append($buttonSaveImage);
$annotatorPNG.append($toolbox);
var $containerAnnotation = $('<div class="' + flagContainerAnnotation + ' ' + flagContainer + '"></div>');
var $canvasAnnotation = $('<canvas class="' + flagCanvasAnnotation + '" height="' + settings.heightCanvas + '" width="' + settings.widthCanvas + '"></canvas>');
let canvas = new fabric.Canvas($canvasAnnotation[0]);
canvas.selection = true;
$canvasAnnotation.data(keyFabric, canvas);
$containerAnnotation.append($canvasAnnotation);
$annotatorPNG.append($containerAnnotation);
$canvasAnnotation.on('object:selected', function(e) {
console.log('Object selected:', e.target);
});
$canvasAnnotation.on('selection:cleared', function() {
console.log('Selection cleared');
});
// Add triggers
$inputUploadImage.on("change", function(event) {
console.log("File uploaded:", event.target.files[0]);
const file = event.target.files[0];
const reader = new FileReader();
let canvas = getCanvas();
reader.onload = function(eventReader) {
fabric.Image.fromURL(eventReader.target.result, function(image) {
canvas.setBackgroundImage(image, canvas.renderAll.bind(canvas), {
scaleX: canvas.width / image.width,
scaleY: canvas.height / image.height,
});
});
};
reader.readAsDataURL(file);
});
$buttonAddArrow.on("click", function() {
console.log("Add Arrow clicked");
let canvas = getCanvas();
const arrow = new fabric.Path('M 0 0 L 200 100', {
fill: $inputColourPicker.val(),
stroke: $inputColourPicker.val(),
strokeWidth: 2,
left: 100,
top: 100,
selectable: true,
});
canvas.add(arrow);
canvas.renderAll();
});
$buttonAddTextbox.on("click", function() {
console.log("Add Textbox clicked");
let canvas = getCanvas();
const textbox = new fabric.Textbox('Type here', {
left: 100,
top: 100,
width: 150,
fontSize: 20,
fill: $inputColourPicker.val(),
selectable: true,
});
canvas.add(textbox);
canvas.renderAll();
});
$selectAddSymbol.on("change", function() {
console.log("Add Symbol changed:", this.value);
if (this.value) {
let canvas = getCanvas();
fabric.Image.fromURL(`symbols/${this.value}`, function(image) {
image.set({
left: 100,
top: 100,
scaleX: 0.5,
scaleY: 0.5,
});
canvas.add(image);
});
this.value = '';
}
});
$inputColourPicker.on("change", function() {
console.log("Colour Picker changed:", this.value);
let canvas = getCanvas();
const activeObject = canvas.getActiveObject();
if (activeObject) {
if (activeObject.type === 'textbox') {
activeObject.set('fill', this.value);
} else {
activeObject.set('fill', this.value);
activeObject.set('stroke', this.value);
}
canvas.renderAll();
}
});
$buttonEraseMode.on("click", function() {
console.log("Erase Mode clicked");
let isEraseMode = $annotatorPNG.data(keyIsEraseMode);
isEraseMode = !isEraseMode;
$annotatorPNG.data(keyIsEraseMode, isEraseMode);
console.log("Erase Mode:", isEraseMode);
this.textContent = isEraseMode ? 'Exit Erase Mode' : 'Erase Mode';
if (isEraseMode) {
// Delete any pre-selected elements when entering erase mode
deleteSelectedObjects();
// Disable selection and drawing
canvas.selection = false;
canvas.isDrawingMode = false;
// Change cursor to indicate erase mode
canvas.defaultCursor = 'crosshair';
canvas.hoverCursor = 'crosshair';
} else {
// Re-enable selection when exiting erase mode
canvas.selection = true;
// Reset cursors
canvas.defaultCursor = 'default';
canvas.hoverCursor = 'move';
}
});
// Object selection in erase mode
$canvasAnnotation.on('selection:created', function() {
console.log("Selection created");
let isEraseMode = $annotatorPNG.data(keyIsEraseMode);
if (isEraseMode) {
deleteSelectedObjects();
}
});
// Object click in erase mode
$canvasAnnotation.on('mouse:down', function(event) {
console.log("Canvas mouse down:", event);
let isEraseMode = $annotatorPNG.data(keyIsEraseMode);
if (isEraseMode && event.target) {
let canvas = getCanvas();
canvas.remove(event.target);
canvas.requestRenderAll();
}
});
// Prevent dragging in erase mode
$canvasAnnotation.on('object:moving', function(event) {
console.log("Canvas object moving:", event);
let isEraseMode = $annotatorPNG.data(keyIsEraseMode);
if (isEraseMode) {
let canvas = getCanvas();
event.target.setCoords();
canvas.remove(event.target);
canvas.requestRenderAll();
}
});
$buttonSaveImage.on("click", function() {
let canvas = getCanvas();
if (confirm("Please ensure there is no sensitive information or PII in your annotations. Do you want to proceed with saving?")) {
const dataURL = canvas.toDataURL({
format: 'png',
quality: 1
});
// Output
console.log("Base64 string:", dataURL);
var a = document.createElement('a');
a.style.display = 'none';
a.href = dataURL;
a.download = settings.fileName;
alert("Image saved as Base64 string. Check the console and Downloads folder for the output.");
}
});
});
};
}(jQuery));

View File

@@ -1,72 +0,0 @@
(function($) {
$.fn.simpleTooltip = function(options) {
// Default settings
var settings = $.extend({
color: '#000000',
backgroundColor: '#FFFFFF',
borderColor: '#CCCCCC',
position: 'top'
}, options);
return this.each(function() {
var $element = $(this);
var tooltipText = $element.attr('data-tooltip');
// Create tooltip element
var $tooltip = $('<div class="simple-tooltip">' + tooltipText + '</div>');
// Apply styles to tooltip
$tooltip.css({
'position': 'absolute',
'display': 'none',
'padding': '5px 10px',
'border': '1px solid ' + settings.borderColor,
'border-radius': '4px',
'background-color': settings.backgroundColor,
'color': settings.color,
'font-size': '12px',
'z-index': 1000
});
// Add tooltip to body
$('body').append($tooltip);
// Show tooltip on hover
$element.on('mouseenter', function() {
var elementOffset = $element.offset();
var elementWidth = $element.outerWidth();
var elementHeight = $element.outerHeight();
var tooltipWidth = $tooltip.outerWidth();
var tooltipHeight = $tooltip.outerHeight();
var left, top;
switch(settings.position) {
case 'top':
left = elementOffset.left + (elementWidth / 2) - (tooltipWidth / 2);
top = elementOffset.top - tooltipHeight - 5;
break;
case 'bottom':
left = elementOffset.left + (elementWidth / 2) - (tooltipWidth / 2);
top = elementOffset.top + elementHeight + 5;
break;
case 'left':
left = elementOffset.left - tooltipWidth - 5;
top = elementOffset.top + (elementHeight / 2) - (tooltipHeight / 2);
break;
case 'right':
left = elementOffset.left + elementWidth + 5;
top = elementOffset.top + (elementHeight / 2) - (tooltipHeight / 2);
break;
}
$tooltip.css({left: left, top: top}).fadeIn(200);
});
// Hide tooltip on mouse leave
$element.on('mouseleave', function() {
$tooltip.fadeOut(200);
});
});
};
}(jQuery));

View File

@@ -1,573 +0,0 @@
// Note: This code assumes you have Mocha, Chai, and Sinon loaded in your test environment
// along with jQuery and html2canvas. You'll also need to include your screen capture plugin.
describe('Screen Capture Plugin', function() {
var $button, sandbox, originalBodyHTML;
beforeEach(function() {
originalBodyHTML = document.body.innerHTML;
// Create a test element and initialize the plugin
$button = $('.' + flagCaptureScreen);
$button.screenshotButton();
// $button = $button.find('button');
// Create a sinon sandbox for mocking
sandbox = sinon.createSandbox();
});
afterEach(function() {
// Clean up
sandbox.restore();
});
after(function() {
document.body.innerHTML = originalBodyHTML;
});
// 1. Initialization and Setup
describe('1. Initialization and Setup', function() {
it('a. should initialize correctly on a given DOM element', function() {
expect($button).to.exist;
});
it('b. should create the button with correct text', function() {
expect($button.text()).to.equal('Capture Screen');
});
it('c. should make the button visible on the page', function() {
expect($button.is(':visible')).to.be.true;
});
});
// 2. Button Functionality
describe('2. Button Functionality', function() {
it('a. should trigger screenshot process on click', function(done) {
// const canvasStub = sinon.stub(document.createElement('canvas'));
sinon.stub(window, 'html2canvas').resolves(document.createElement('canvas'));
// await waitForClick($button);
$button.click();
setTimeout(() => {
expect(html2canvas.called).to.be.true;
expect(html2canvas.callCount).to.equal(1);
html2canvas.restore();
done();
}, 1000);
});
it('b. should hide button during screenshot process',
/*
async function() {
sinon.stub(window, 'html2canvas').resolves(document.createElement('canvas'));
let resolve;
const promise = new Promise((r) => resolve = r);
function handleButtonClick() {
resolve();
$button.off('click', handleButtonClick);
}
$button.on("click", function() {
handleButtonClick();
});
$button.click();
expect($button.hasClass(flagIsHidden)).to.be.true;
html2canvas.restore();
}
*/
function(done) {
sinon.stub(window, 'html2canvas').resolves(document.createElement('canvas'));
$button.click();
expect($button.hasClass(flagIsHidden)).to.be.true;
html2canvas.restore();
done();
}
);
it('c. should show button after screenshot is taken', function(done) {
sinon.stub(window, 'html2canvas').resolves(document.createElement('canvas'));
/*
await waitForClick($button).then(() => {
setTimeout(() => {
expect($button.hasClass(flagIsHidden)).to.be.false;
// html2canvas.restore();
}, 100); // delay for screenshot and callback process
})
.catch((err) => {
html2canvas.restore();
throw err;
});
*/
$button.click();
setTimeout(() => {
expect($button.hasClass(flagIsHidden)).to.be.false;
html2canvas.restore();
done();
}, 1000); // delay for screenshot and callback process
});
});
// 3. Input Handling
describe('3. Input Handling', function() {
let $input, $textarea;
beforeEach(function() {
$input = $('<input type="text" value="test">').appendTo('body');
$textarea = $('<textarea>test</textarea>').appendTo('body');
});
afterEach(function() {
$input.remove();
$textarea.remove();
});
it('a. should clear input and textarea values during screenshot', function(done) {
sinon.stub(window, 'html2canvas').resolves(document.createElement('canvas'));
$button.click();
expect($input.val()).to.equal('');
expect($textarea.val()).to.equal('');
html2canvas.restore();
done();
});
it('b. should restore input and textarea values after screenshot', function(done) {
sinon.stub(window, 'html2canvas').resolves(document.createElement('canvas'));
/*
await waitForClick($button).then(() => {
setTimeout(() => {
expect($input.val()).to.equal('test');
expect($textarea.val()).to.equal('test');
}, 1000); // delay for screenshot and callback process
})
/*
.catch((err) => {
html2canvas.restore();
throw err;
})*
;
*/
$button.click();
setTimeout(() => {
expect($input.val()).to.equal('test');
expect($textarea.val()).to.equal('test');
done();
}, 1000);
html2canvas.restore();
});
});
// 4. Modal and Floating Element Handling
describe('4. Modal and Floating Element Handling', function() {
let $modal;
beforeEach(function() {
$modal = $('<div class="modal">Modal Content</div>').appendTo('body');
});
afterEach(function() {
$modal.remove();
});
it('a. should capture visible modals', async function() {
sinon.stub(window, 'html2canvas').callsFake(function(element) {
expect($(element).find('.modal').length).to.equal(5);
return Promise.resolve(document.createElement('canvas'));
});
await waitForClick($button);
html2canvas.restore();
});
});
// 5. HTML2Canvas Integration
describe('5. HTML2Canvas Integration', function() {
it('a. should call html2canvas with correct parameters', async function() {
const html2canvasStub = sinon.stub(window, 'html2canvas').resolves(document.createElement('canvas'));
await waitForClick($button);
html2canvas.restore();
expect(html2canvasStub.calledWith(document.body)).to.be.true;
});
it('b. should handle html2canvas errors gracefully', async function() {
sinon.stub(window, 'html2canvas').rejects(new Error('Test error'));
sinon.stub(console, 'error');
await waitForClick($button);
html2canvas.restore();
expect(console.error.called).to.be.true;
console.error.restore();
});
});
// 6. Screenshot Generation
describe('6. Screenshot Generation', function() {
/* Base64 string used instead of Blob
it('a. should create a blob from the canvas', async function() {
const canvas = document.createElement('canvas');
sinon.stub(window, 'html2canvas').resolves(canvas);
sinon.stub(canvas, 'toBlob').callsArgWith(0, new Blob());
await waitForClick($button);
html2canvas.restore();
expect(canvas.toBlob.called).to.be.true;
canvas.toBlob.restore();
});
*/
it('b. should generate a Base64 PNG string when saving is confirmed', async function() {
const consoleStub = sinon.stub(console, 'log');
await waitForClick($button).then(() => {
setTimeout(() => {
expect(consoleStub.callCount).to.equal(2);
const base64String = consoleStub.getCall(0).args[1];
expect(base64String).to.be.a('string');
expect(base64String).to.match(/^data:image\/png;base64,/);
consoleStub.restore();
}, 1000); // delay for screenshot and callback process
});
});
});
// 7. Download Functionality
describe('7. Download Functionality', function() {
it('a. should create a temporary anchor element for download', async function() {
// Stub document.createElement
createElementStub = sinon.stub(document, 'createElement').callsFake(function(tagName) {
if (tagName === 'a') {
return {
style: {},
href: '',
download: '',
click: sinon.spy()
};
}
});
// Stub document.body.appendChild and removeChild
appendChildStub = sinon.stub(document.body, 'appendChild');
removeChildStub = sinon.stub(document.body, 'removeChild');
// Mock blob and URL
blobMock = new Blob(['test'], { type: 'text/plain' });
urlMock = 'blob:http://example.com/test';
sinon.stub(URL, 'createObjectURL').returns(urlMock);
sinon.stub(URL, 'revokeObjectURL');
await waitForClick($button).then(() => {
setTimeout(() => {
// Assertions
expect(createElementStub.calledWith('a')).to.be.true;
expect(appendChildStub.calledOnce).to.be.true;
expect(removeChildStub.calledOnce).to.be.true;
const aElement = appendChildStub.getCall(0).args[0];
expect(aElement.href).to.equal(urlMock);
expect(aElement.download).to.equal('screenshot.png'); // Assuming settings.fileName is 'screenshot.png'
}, 1000);
});
/*
const appendChildStub = sandbox.stub(document.body, 'appendChild').callsFake((element) => {
console.log("attempting to append element: ", element);
if (element.tagName === 'IFRAME') {
// Allow iframe to be appended normally
document.body.appendChild.wrappedMethod.call(document.body, element);
}
});
sandbox.stub(document.body, 'removeChild');
sandbox.stub(URL, 'createObjectURL').returns('blob:test');
sandbox.stub(URL, 'revokeObjectURL');
await waitForClick($button).then(() => {
setTimeout(() => {
expect(document.body.appendChild.calledOnce).to.be.true;
expect(document.body.appendChild.args[0][0].tagName).to.equal('A');
}, 1000); // delay for screenshot and callback process
});
*/
});
it('b. should click the temporary anchor element programmatically', async function() {
const fakeAnchor = {
style: {},
click: sinon.spy()
};
sandbox.stub(document, 'createElement').returns(fakeAnchor);
await waitForClick($button);
expect(fakeAnchor.click.calledOnce).to.be.true;
});
it('c. should remove the temporary anchor after download', async function() {
sandbox.stub(document.body, 'removeChild');
await waitForClick($button);
expect(document.body.removeChild.calledOnce).to.be.true;
});
});
// 8. Cross-browser Compatibility
describe('8. Cross-browser Compatibility', function() {
it('a. should work in Chrome-like environments', function() {
// Assuming we're running tests in a Chrome-like environment
expect(() => $button.screenshotButton()).to.not.throw();
});
// Additional browser-specific tests would go here
// These might need to be run in different environments or with browser mocks
});
// 9. Performance
describe('9. Performance', function() {
it('a. should capture and generate screenshot within acceptable time', async function() {
this.timeout(5000); // Adjust timeout as needed
const startTime = performance.now();
await waitForClick($button);
const endTime = performance.now();
const duration = endTime - startTime;
expect(duration).to.be.below(1000); // Adjust threshold as needed
});
// Additional performance tests with different page complexities would go here
});
// 10. Error Handling
describe('10. Error Handling', function() {
it('a. should log error when html2canvas is not loaded', async function() {
const consoleErrorStub = sandbox.stub(console, 'error');
const originalHtml2Canvas = window.html2canvas;
delete window.html2canvas;
await waitForClick($button);
expect(consoleErrorStub.calledOnce).to.be.true;
expect(consoleErrorStub.args[0][0]).to.include('html2canvas is not loaded');
// Restore html2canvas
window.html2canvas = originalHtml2Canvas;
});
it('a. should handle errors during capture process', async function() {
sandbox.stub(window, 'html2canvas').rejects(new Error('Capture failed'));
const consoleErrorStub = sandbox.stub(console, 'error');
await waitForClick($button);
expect(consoleErrorStub.calledOnce).to.be.true;
expect(consoleErrorStub.args[0][0]).to.include('Capture failed');
});
});
// Configuration Options
describe('11. Configuration Options', function() {
it('11.1 should apply custom button text correctly', function() {
const customText = 'Capture Screen';
$button.screenshotButton({ buttonText: customText });
expect($button.text()).to.equal(customText);
});
it('11.2 should use custom filename for the downloaded image', async function() {
const customFileName = 'custom-screenshot.png';
$button.screenshotButton({ fileName: customFileName });
// Mock html2canvas and URL.createObjectURL
global.html2canvas = sinon.stub().resolves({ toBlob: (callback) => callback(new Blob()) });
global.URL.createObjectURL = sinon.stub().returns('blob:url');
// Mock anchor creation and click
const anchorMock = {
style: {},
click: sinon.spy(),
remove: sinon.spy()
};
sinon.stub(document, 'createElement').returns(anchorMock);
await waitForClick($button);
expect(anchorMock.download).to.equal(customFileName);
document.createElement.restore();
});
it('11.3 should respect custom modal selectors during capture', async function() {
const customSelector = '.custom-modal';
$button.screenshotButton({ modalsSelector: customSelector });
// Create a custom modal element
$('<div class="custom-modal">Custom Modal</div>').appendTo('body');
// Mock html2canvas
global.html2canvas = sinon.spy((element, options) => {
expect(options.ignoreElements).to.be.a('function');
const customModal = document.querySelector(customSelector);
expect(options.ignoreElements(customModal)).to.be.false;
done();
return Promise.resolve({ toBlob: () => {} });
});
await waitForClick($button);
});
});
// Accessibility
describe('12. Accessibility', function() {
it('12.1 should have appropriate ARIA attributes', function() {
$button.screenshotButton(defaultOptions);
expect($button.attr('role')).to.equal('button');
expect($button.attr('aria-label')).to.equal(defaultOptions.buttonText);
});
it('12.2 should be keyboard accessible', async function() {
$button.screenshotButton(defaultOptions);
$button.on('keydown', function(e) {
if (e.which === 13) { // Enter key
done();
}
});
const event = new KeyboardEvent('keydown', { 'keyCode': 13 });
$button[0].dispatchEvent(event);
});
});
// Security
describe('13. Security', function() {
it('13.1 should not capture sensitive information in inputs and textareas', async function() {
$button.screenshotButton(defaultOptions);
// Create test input and textarea with sensitive information
$('<input type="text" value="sensitive-info">').appendTo('body');
$('<textarea>confidential-data</textarea>').appendTo('body');
// Mock html2canvas
global.html2canvas = sinon.spy(() => {
const inputs = document.querySelectorAll('input, textarea');
inputs.forEach(input => {
expect(input.value).to.be.empty;
});
done();
return Promise.resolve({ toBlob: () => {} });
});
await waitForClick($button);
});
it('13.2 should restore input and textarea values after capture', async function() {
$button.screenshotButton(defaultOptions);
const inputValue = 'sensitive-info';
const textareaValue = 'confidential-data';
// Create test input and textarea with sensitive information
$('<input type="text" value="' + inputValue + '">').appendTo('body');
$('<textarea>' + textareaValue + '</textarea>').appendTo('body');
// Mock html2canvas and URL.createObjectURL
global.html2canvas = sinon.stub().resolves({ toBlob: (callback) => callback(new Blob()) });
global.URL.createObjectURL = sinon.stub().returns('blob:url');
await waitForClick($button);
setTimeout(() => {
const inputs = document.querySelectorAll('input, textarea');
inputs.forEach(input => {
if (input.tagName === 'INPUT') {
expect(input.value).to.equal(inputValue);
} else if (input.tagName === 'TEXTAREA') {
expect(input.value).to.equal(textareaValue);
}
});
done();
}, 0);
});
});
// CSS Interaction
describe('14. CSS Interaction', function() {
it('14.1 should not break existing page styles', function() {
const originalStyles = getComputedStyle(document.body);
$button.screenshotButton();
const newStyles = getComputedStyle(document.body);
expect(originalStyles.cssText).to.equal(newStyles.cssText);
});
it('14.2 should apply correct button styling', function() {
$button.screenshotButton();
const $button = $button.find('button');
const buttonStyles = getComputedStyle($button[0]);
expect(buttonStyles.display).to.not.equal('none');
// Add more specific style checks as per your plugin's CSS
});
});
// jQuery Plugin Standards
describe('15. jQuery Plugin Standards', function() {
it('15.1 should return jQuery object for chaining', function() {
const result = $button.screenshotButton();
expect(result).to.equal($button);
});
it('15.2 should initialize plugin on multiple elements', function() {
$('body').append('<div class="test-class"></div><div class="test-class"></div>');
$('.test-class').screenshotButton();
expect($('.test-class').find('button').length).to.equal(2);
});
});
// Memory Management
describe('16. Memory Management', function() {
it('16.1 should not leak memory on repeated initialization and destruction', function() {
const initialMemory = performance.memory ? performance.memory.usedJSHeapSize : 0;
for (let i = 0; i < 100; i++) {
$button.screenshotButton();
$button.empty();
}
const finalMemory = performance.memory ? performance.memory.usedJSHeapSize : 0;
expect(finalMemory - initialMemory).to.be.below(1000000); // Less than 1MB increase
});
it('16.2 should remove all created DOM elements after use', function() {
$button.screenshotButton();
const initialChildCount = $button[0].childElementCount;
$button.find('button').click();
// Assuming the screenshot process is synchronous for this test
expect($button[0].childElementCount).to.equal(initialChildCount);
});
});
// Responsiveness
describe('17. Responsiveness', function() {
it('17.1 should behave correctly on different screen sizes', function() {
const viewports = [
{width: 320, height: 568}, // iPhone 5
{width: 1024, height: 768}, // iPad
{width: 1920, height: 1080} // Full HD
];
viewports.forEach(size => {
$button.width(size.width).height(size.height);
$button.screenshotButton();
const $button = $button.find('button');
expect($button.is(':visible')).to.be.true;
expect($button.width()).to.be.at.most(size.width);
});
});
it('17.2 should capture accurate viewport in screenshot', async function() {
$button.width(800).height(600);
$button.html('<div id="content" style="width: 100%; height: 100%; background-color: red;"></div>');
$button.screenshotButton();
const $button = $button.find('button');
await waitForClick($button);
// Mock html2canvas to check if it's called with correct dimensions
sinon.replace(window, 'html2canvas', sinon.fake.returns(Promise.resolve({
toBlob: (callback) => callback(new Blob(['fakepngdata'], {type: 'image/png'}))
})));
setTimeout(() => {
expect(html2canvas.calledOnce).to.be.true;
const args = html2canvas.firstCall.args[1];
expect(args.width).to.equal(800);
expect(args.height).to.equal(600);
sinon.restore();
done();
}, 100);
});
});
});

View File

@@ -1,174 +0,0 @@
// Mock dependencies
jest.mock('fabric');
// Setup
let container, canvas;
beforeEach(() => {
// Set up our document body
document.body.innerHTML = '<div class="image-annotator"></div>';
container = document.querySelector('.image-annotator');
// Mock Fabric.Canvas
canvas = new fabric.Canvas();
fabric.Canvas.mockImplementation(() => canvas);
// Initialize our plugin
$('.image-annotator').imageAnnotator();
});
// Initialization and Setup
test('1. Plugin initializes correctly', () => {
expect(container.querySelector('canvas')).not.toBeNull();
});
test('2. Canvas is created with correct dimensions', () => {
expect(canvas.setWidth).toHaveBeenCalledWith(800);
expect(canvas.setHeight).toHaveBeenCalledWith(600);
});
test('3. All UI elements are present after initialization', () => {
expect(container.querySelector('#imageUpload')).not.toBeNull();
expect(container.querySelector('#addArrow')).not.toBeNull();
expect(container.querySelector('#addTextbox')).not.toBeNull();
expect(container.querySelector('#eraseElement')).not.toBeNull();
expect(container.querySelector('#saveButton')).not.toBeNull();
});
// Image Upload and Display
test('4. PNG file can be successfully uploaded', () => {
const file = new File([''], 'test.png', { type: 'image/png' });
const event = { target: { files: [file] } };
const fileReader = {
readAsDataURL: jest.fn(),
onload: null
};
window.FileReader = jest.fn(() => fileReader);
$('#imageUpload').trigger('change', event);
expect(fileReader.readAsDataURL).toHaveBeenCalledWith(file);
});
test('5. Uploaded image is displayed correctly on the canvas', () => {
// This test would be similar to test 4, but would also check that fabric.Image.fromURL is called
// and that setBackgroundImage is called on the canvas
});
test('6. Image is scaled appropriately to fit the canvas', () => {
// Similar to test 5, but would check the scaling parameters passed to setBackgroundImage
});
test('7. Invalid file types are handled', () => {
const file = new File([''], 'test.jpg', { type: 'image/jpeg' });
const event = { target: { files: [file] } };
console.error = jest.fn();
$('#imageUpload').trigger('change', event);
expect(console.error).toHaveBeenCalledWith('Please upload a PNG file.');
});
// Arrow Addition
test('9. Clicking "Add Arrow" creates a new arrow on the canvas', () => {
$('#addArrow').click();
expect(fabric.Path).toHaveBeenCalled();
expect(canvas.add).toHaveBeenCalled();
});
// Textbox Addition
test('12. Clicking "Add Textbox" creates a new textbox on the canvas', () => {
$('#addTextbox').click();
expect(fabric.Textbox).toHaveBeenCalled();
expect(canvas.add).toHaveBeenCalled();
});
// Element Manipulation
test('16. Arrows can be selected, moved, resized, and rotated', () => {
const arrow = new fabric.Path();
canvas.getActiveObject.mockReturnValue(arrow);
arrow.set = jest.fn();
canvas.trigger('object:modified', { target: arrow });
expect(arrow.set).toHaveBeenCalled();
});
// Erasing Elements
test('20. Clicking "Erase Element" removes the currently selected element', () => {
const object = new fabric.Object();
canvas.getActiveObject.mockReturnValue(object);
$('#eraseElement').click();
expect(canvas.remove).toHaveBeenCalledWith(object);
});
// Saving Functionality
test('24. Clicking "Save" triggers the confirmation dialog', () => {
window.confirm = jest.fn(() => true);
$('#saveButton').click();
expect(window.confirm).toHaveBeenCalled();
});
test('26. Confirming the dialog generates a Base64 PNG string', () => {
window.confirm = jest.fn(() => true);
canvas.toDataURL = jest.fn(() => 'data:image/png;base64,ABC123');
$('#saveButton').click();
expect(canvas.toDataURL).toHaveBeenCalledWith({ format: 'png', quality: 1 });
});
// Edge Cases and Error Handling
test('29. Plugin handles initialization on an invalid DOM element', () => {
console.error = jest.fn();
$('.non-existent-element').imageAnnotator();
expect(console.error).toHaveBeenCalledWith('Invalid element for image annotator');
});
// Performance
test('34. Rendering performance with many elements', () => {
const start = performance.now();
for (let i = 0; i < 100; i++) {
canvas.add(new fabric.Path());
}
canvas.renderAll();
const end = performance.now();
expect(end - start).toBeLessThan(1000); // Assuming 1 second is our performance threshold
});
// Browser Compatibility
// Note: This would typically be done with a tool like Selenium or Cypress for cross-browser testing
// Accessibility
test('38. Keyboard navigation for adding elements', () => {
const event = new KeyboardEvent('keydown', {'key': 'Enter'});
$('#addArrow').focus();
$('#addArrow')[0].dispatchEvent(event);
expect(fabric.Path).toHaveBeenCalled();
});
// Security
test('41. Confirmation dialog appears consistently before saving', () => {
window.confirm = jest.fn(() => true);
$('#saveButton').click();
$('#saveButton').click();
$('#saveButton').click();
expect(window.confirm).toHaveBeenCalledTimes(3);
});

View File

@@ -1,47 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Screen Capture Test Page</title>
<link rel="stylesheet" href="capture-screen.css">
</head>
<body>
<div class="content-wrapper">
<main>
<h1>Screen Capture Test Page</h1>
<p>This page is used to test the screen capture functionality.</p>
<input type="text" id="inputTestText" value="Test input">
<textarea id="textareaTest">Test textarea</textarea>
<input type="number" id="inputTestNumber" value="2" />
<input type="password" id="inputTestPassword" value="password123">
<button class="capture-screen">Capture Screen</button>
</main>
</div>
<div id="modalTest" class="modal">
<div class="modal-content">
<h2>Test Modal</h2>
<p>This is a test modal.</p>
</div>
</div>
<div id="mocha"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/8.3.2/mocha.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/4.3.4/chai.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sinon.js/10.0.0/sinon.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.3.2/html2canvas.min.js"></script>
<script src="plugin_capture_screen.js"></script>
<script>
mocha.setup('bdd');
const expect = chai.expect;
</script>
<script src="test_plugin_capture_screen_Mocha.js"></script>
<script>
var flagCaptureScreen = "capture-screen";
mocha.run();
</script>
</body>
</html>

View File

@@ -1,110 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Screen Capture Control</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
<link rel="stylesheet" href="capture-screen.css">
<style>
#captureButton {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 9999;
padding: 10px 20px;
font-size: 16px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
#captureButton:hover {
background-color: #0056b3;
}
.sensitive-data {
color: transparent;
background-color: #ccc;
}
</style>
</head>
<body>
<header>
<h1>Website Title</h1>
</header>
<div class="content-wrapper">
<main>
<h2>Main Content</h2>
<p>This is where the main content of your page goes. You can add articles, blog posts, or any other primary content here.</p>
<input type="text" value="Test 1" />
<input type="number" value="2" />
<textarea>Test 3</textarea>
<button class="capture-screen">Capture Screen</button>
<!-- Notification Widget -->
<div id="notification-widget" class="widget">
<h3>Notifications</h3>
<p>You have 3 new messages.</p>
</div>
<a href="#notification-widget" id="notification-toggle" class="widget-toggle">Toggle Notifications</a>
<!-- Chat Widget -->
<div id="chat-widget" class="widget">
<h3>Chat</h3>
<p>Chat content goes here...</p>
</div>
<a href="#chat-widget" id="chat-toggle" class="widget-toggle">Toggle Chat</a>
<!-- Quick Settings Widget -->
<div id="settings-widget" class="widget">
<h3>Quick Settings</h3>
<p>Adjust your settings here...</p>
</div>
<a href="#settings-widget" id="settings-toggle" class="widget-toggle">Toggle Settings</a>
</main>
</div>
<script>
$(document).ready(function() {
$('.capture-screen').on('click', function() {
// Hide the capture button
$(this).hide();
// Mask sensitive data
$('input, textarea').each(function() {
$(this).addClass('sensitive-data');
$(this).attr('data-original-value', $(this).val());
$(this).val('********');
});
// Capture the screen
html2canvas(document.body).then(function(canvas) {
// Convert canvas to PNG data URL
var dataURL = canvas.toDataURL('image/png');
// Create a temporary link and trigger download
var link = document.createElement('a');
link.href = dataURL;
link.download = 'screen_capture.png';
link.click();
// Restore sensitive data
$('input, textarea').each(function() {
$(this).removeClass('sensitive-data');
$(this).val($(this).attr('data-original-value'));
$(this).removeAttr('data-original-value');
});
// Show the capture button again
$('.capture-screen').show();
});
});
});
</script>
</body>
</html>

View File

@@ -1,60 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple Layout Template</title>
<link rel="stylesheet" href="capture-screen.css">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
<script src="./plugin_capture_screen.js"></script>
</head>
<body>
<header>
<h1>Website Title</h1>
</header>
<div class="content-wrapper">
<main>
<h2>Main Content</h2>
<p>This is where the main content of your page goes. You can add articles, blog posts, or any other primary content here.</p>
<input type="text" value="Test 1" />
<input type="number" value="2" />
<textarea>Test 3</textarea>
<button class="capture-screen">Capture Screen</button>
<!-- Notification Widget -->
<div id="notification-widget" class="widget">
<h3>Notifications</h3>
<p>You have 3 new messages.</p>
</div>
<a href="#notification-widget" id="notification-toggle" class="widget-toggle">Toggle Notifications</a>
<!-- Chat Widget -->
<div id="chat-widget" class="widget">
<h3>Chat</h3>
<p>Chat content goes here...</p>
</div>
<a href="#chat-widget" id="chat-toggle" class="widget-toggle">Toggle Chat</a>
<!-- Quick Settings Widget -->
<div id="settings-widget" class="widget">
<h3>Quick Settings</h3>
<p>Adjust your settings here...</p>
</div>
<a href="#settings-widget" id="settings-toggle" class="widget-toggle">Toggle Settings</a>
</main>
</div>
</body>
<script>
$(document).ready(function() {
var flagCaptureScreen = "capture-screen";
$("." + flagCaptureScreen).screenshotButton({
buttonText: "Capture Screen",
fileName: "screenshot.png",
});
});
</script>
</html>

View File

@@ -1,63 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image Annotation Control</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/5.3.1/fabric.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="plugin_display_png_v1a.js"></script>
<style>
#annotationContainer {
position: relative;
width: 800px;
height: 600px;
border: 1px solid #ccc;
margin: 20px auto;
}
#canvas {
border: 1px solid #ccc;
}
#toolbox {
margin-bottom: 10px;
}
button {
margin-right: 5px;
}
</style>
</head>
<body>
<div class="annotatorPNG">
<div id="toolbox">
<input type="file" id="imageUpload" accept="image/png">
<button id="addArrow">Add Arrow</button>
<button id="addTextbox">Add Textbox</button>
<select id="symbolSelect">
<option value="">Select Symbol</option>
<!-- Options will be populated dynamically -->
</select>
<input type="color" id="colorPicker" value="#ff0000">
<button id="eraseMode">Erase Mode</button>
<button id="saveImage">Save Image</button>
</div>
<div id="annotationContainer">
<canvas id="canvas" width="800" height="600"></canvas>
</div>
</div>
</body>
<script>
// $(document).ready(hookupPageDisplayPng);
// change to flags - enables multiple annotatorPNGs per webpage
var idButtonAddArrow = "#addArrow";
var idButtonAddTextbox = "#addTextbox";
var idButtonEraseMode = "#eraseMode";
var idButtonSaveImage = "#saveImage";
var idColorPicker = "#colorPicker";
var idImageUpload = "#imageUpload";
var idSelectSymbol = "#symbolSelect";
$(document).ready(function() {
hookupPageDisplayPng();
});
</script>
</html>

View File

@@ -1,36 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image Annotation Control</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/5.3.1/fabric.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="plugin_display_png.js"></script>
<link rel="stylesheet" href="display-png.css">
</head>
<body>
<div class="annotator-png"></div>
</body>
<script>
var flagAnnotatorPNG = "annotator-png";
var flagToolbox = "annotator-png-toolbox";
var flagContainer = "annotator-png-container";
var flagContainerAnnotation = "annotator-png-container-annotation";
var flagUploadImage = "annotator-png-upload-image";
var flagAddArrow = "annotator-png-add-arrow";
var flagAddTextbox = "annotator-png-add-textbox";
var flagAddSymbol = "annotator-png-add-symbol";
var flagColourPicker = "annotator-png-colour-picker";
var flagEraseMode = "annotator-png-erase-mode";
var flagSaveImage = "annotator-png-save-image";
var flagCanvasAnnotation = "annotator-png-canvas-annotation";
var keyFabric = "fabric";
var isEraseMode = false; // "isEraseMode";
$(document).ready(function() {
$("." + flagAnnotatorPNG).annotatorPNG({
});
});
</script>
</html>

View File

@@ -1,98 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Modal/Floating Element Examples</title>
<style>
/* Common styles */
body {
font-family: Arial, sans-serif;
line-height: 1.6;
margin: 0;
padding: 20px;
}
.btn {
padding: 10px 20px;
background-color: #007bff;
color: white;
border: none;
cursor: pointer;
}
/* Method 1: CSS Positioning */
.modal-overlay {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
}
.modal-content {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: white;
padding: 20px;
border-radius: 5px;
}
#modal1:target {
display: block;
}
/* Method 2: Dialog Element */
dialog::backdrop {
background-color: rgba(0, 0, 0, 0.5);
}
dialog {
padding: 20px;
border-radius: 5px;
border: none;
}
/* Method 3: Floating Element */
.floating-element {
position: fixed;
bottom: 20px;
right: 20px;
background-color: white;
padding: 20px;
border-radius: 5px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
</style>
</head>
<body>
<h1>Modal/Floating Element Examples</h1>
<!-- Method 1: CSS Positioning -->
<h2>1. CSS Positioning</h2>
<a href="#modal1" class="btn">Open Modal 1</a>
<div id="modal1" class="modal-overlay">
<div class="modal-content">
<h2>Modal 1</h2>
<p>This is a modal using CSS positioning.</p>
<a href="#" class="btn">Close</a>
</div>
</div>
<!-- Method 2: Dialog Element -->
<h2>2. Dialog Element</h2>
<button class="btn" onclick="document.getElementById('modal2').showModal()">Open Modal 2</button>
<dialog id="modal2">
<h2>Modal 2</h2>
<p>This is a modal using the dialog element.</p>
<button class="btn" onclick="document.getElementById('modal2').close()">Close</button>
</dialog>
<!-- Method 3: Floating Element -->
<h2>3. Floating Element</h2>
<div class="floating-element">
<h2>Floating Element</h2>
<p>This is a floating element using fixed positioning.</p>
</div>
</body>
</html>

View File

@@ -1,89 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Floating Widgets Examples</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
}
.widget {
position: fixed;
background-color: #f0f0f0;
border: 1px solid #ccc;
border-radius: 5px;
padding: 10px;
display: none;
}
.widget-toggle {
position: fixed;
padding: 10px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
#notification-widget {
top: 20px;
right: 20px;
width: 250px;
}
#notification-toggle {
top: 20px;
right: 20px;
}
#chat-widget {
bottom: 20px;
right: 20px;
width: 300px;
height: 400px;
}
#chat-toggle {
bottom: 20px;
right: 20px;
}
#settings-widget {
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 200px;
}
#settings-toggle {
top: 20px;
left: 20px;
}
.widget:target {
display: block;
}
</style>
</head>
<body>
<h1>Floating Widgets Examples</h1>
<p>Click the buttons to toggle the widgets.</p>
<!-- Notification Widget -->
<div id="notification-widget" class="widget">
<h3>Notifications</h3>
<p>You have 3 new messages.</p>
</div>
<a href="#notification-widget" id="notification-toggle" class="widget-toggle">Toggle Notifications</a>
<!-- Chat Widget -->
<div id="chat-widget" class="widget">
<h3>Chat</h3>
<p>Chat content goes here...</p>
</div>
<a href="#chat-widget" id="chat-toggle" class="widget-toggle">Toggle Chat</a>
<!-- Quick Settings Widget -->
<div id="settings-widget" class="widget">
<h3>Quick Settings</h3>
<p>Adjust your settings here...</p>
</div>
<a href="#settings-widget" id="settings-toggle" class="widget-toggle">Toggle Settings</a>
</body>
</html>

View File

@@ -1,13 +0,0 @@
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="./plugin_capture_screen.js"></script>
<script>
$(document).ready(function() {
$('[data-tooltip]').simpleTooltip({
color: '#ffffff',
backgroundColor: '#000000',
position: 'bottom'
});
});
</script>
<button data-tooltip="This is a tooltip">Hover me</button>