I am attempting to use PhantomJs to crawl our ASP.Net web app and take screenshots of a list of pages defined in a simple text file of URLs. I have been able to get it working fine for pages not behind the log-in wall, but can't seem to get my PhantomJs instance to get authenticated. Log messages show that I'm doing things in the right order with my two interval functions - any ideas how to make sure I'm logged in first?
var fs = require('fs'),
system = require('system');
var content = '',
f = null,
lines = null,
pages =null,
destinations = null,
eol = system.os.name == 'windows' ? "\r\n" : "\n";
//read in a line break separated list of urls
//page at index 0 is the login page
try {
f = fs.open(".\\urls.txt", "r");
content = f.read();
} catch (e) {
console.log(e);
}
if (f) {
f.close();
}
if (content) {
lines = content.split(eol);
pages = new Array();
destinations = new Array();
for (var i = 0, len = lines.length; i < len; i++) {
var pageName = lines[i].substring(lines[i].lastIndexOf('/') + 1);
pages[i] = pageName;
destinations[i] = ".\\NewScreenShot\\" + pageName + '.png';
}
}
console.log('Pages found: ' + pages.length);
var page = require('webpage').create();
var loginIndex = 0;
var loginInProgress = false;
var loginSteps = [
function() {
//Enter Credentials
page.evaluate(function() {
document.getElementById("txtusername").value = "ausername#mysite.com";
document.getElementById("txtpassword").value ="12345678";
return;
});
},
function() {
//Login
page.evaluate(function() {
var arr = document.getElementById("form1");
var i;
for (i=0; i < arr.length; i++) {
if (arr[i].getAttribute('method') == "POST") {
arr[i].submit();
return;
}
}
});
}
];
var LoadPage = function() {
if (!loadInProgress && pageindex < pages.length) {
console.log("image " + (pageindex + 1) + " of " + lines.length);
page.open(lines[pageindex]);
}
if (pageindex == lines.length) {
console.log("<< Image render complete! >>");
phantom.exit();
}
}
//PNG RENDER
var pageindex = 0;
var loadInProgress = false;
var interval = setInterval(LoadPage, 500);
page.onLoadStarted = function() {
loadInProgress = true;
if(pageindex == 0) {
loginInProgress = true;
}
console.log('page ' + (pageindex + 1) + ' load started');
};
page.onLoadFinished = function() {
loadInProgress = false;
if(pageindex == 0)
{
loginInProgress = false;
console.log("stopping page interval");
clearInterval(interval);
}
page.evaluate(
function () {
var scaleVal = "scale("+arguments[0] || '1.0'+")";
document.body.style.webkitTransform = scaleVal;
}
);
console.log("rendering:" + destinations[pageindex]);
page.render(destinations[pageindex]); // RENDER PAGE //
if (pageindex == 0){
var loginInterval = setInterval(function() {
if (!loginInProgress && typeof loginSteps[loginIndex] == "function") {
console.log("login step: " + loginIndex )
loginSteps[loginIndex]();
loginIndex++;
}
if (typeof loginSteps[loginIndex] != "function") {
console.log("stopping login interval");
clearInterval(loginInterval);
console.log("starting page interval");
setInterval(LoadPage, 500);
}
}, 50);
}
pageindex++;
}
Turns out the problem was form submit vs button click. working code below:
var urlsLocation = "C:\\PhantomJs\\urls.txt";
var newScreenshotFolder = "C:\\PhantomJs\\NewScreenShot\\";
var fs = require('fs'),
system = require('system');
var content = '',
f = null,
lines = null,
pages =null,
destinations = null,
eol = system.os.name == 'windows' ? "\r\n" : "\n";
//read in a return separated list of urls
try {
f = fs.open(urlsLocation, "r");
content = f.read();
} catch (e) {
console.log(e);
}
if (f) {
f.close();
}
if (content) {
lines = content.split(eol);
pages = new Array();
destinations = new Array();
for (var i = 0, len = lines.length; i < len; i++) {
var pageName = lines[i].substring(lines[i].lastIndexOf('/') + 1);
pages[i] = pageName;
destinations[i] = newScreenshotFolder + pageName.replace(/[^a-zA-Z0-9\.]/g, "") + '.png';
}
}
console.log('Pages found: ' + pages.length);
var page = require('webpage').create();
var loginIndex = 0;
var loginInProgress = false;
var loginCompleted = false;
var loginSteps = [
function() {
//Enter Credentials
page.evaluate(function() {
document.getElementById("txtusername").value = "testemail#gmail.com";
document.getElementById("txtpassword").value = "12345678";
return;
});
},
function() {
//Login
page.evaluate(function() {
document.getElementById("btnLogin").click();
return;
});
}
];
var LoadPage = function() {
if (!loadInProgress && pageindex < pages.length) {
console.log("image " + (pageindex + 1) + " of " + lines.length);
page.open(lines[pageindex]);
}
if (pageindex == lines.length) {
console.log("<< Image render complete! >>");
phantom.exit();
}
}
//PNG RENDER
var pageindex = 0;
var loadInProgress = false;
var interval = setInterval(LoadPage, 500);
page.onLoadStarted = function() {
loadInProgress = true;
if(pageindex == 0) {
loginInProgress = true;
}
console.log('page ' + (pageindex + 1) + ' load started');
};
page.onLoadFinished = function() {
loadInProgress = false;
if(pageindex == 0)
{
loginInProgress = false;
console.log("stopping page interval");
clearInterval(interval);
}
page.evaluate(
function () {
var scaleVal = "scale("+arguments[0] || '1.0'+")";
document.body.style.webkitTransform = scaleVal;
}
);
console.log("rendering:" + destinations[pageindex]);
page.render(destinations[pageindex]); // RENDER PAGE //
if (pageindex == 0){
var loginInterval = setInterval(function() {
if (!loginInProgress && typeof loginSteps[loginIndex] == "function") {
console.log("login step: " + loginIndex )
loginSteps[loginIndex]();
loginIndex++;
}
if (typeof loginSteps[loginIndex] != "function") {
console.log("stopping login interval");
clearInterval(loginInterval);
console.log("starting page interval");
setInterval(LoadPage, 1000);
}
}, 50);
}
pageindex++;
}
Related
I've been working on an app that uses webRTC and it works perfectly on all of MY devices from different networks. However, when other people try to use it from their devices, some can connect and some can't. I collected all the WebRTC chrome internal dumps and attached some of them below.
Local dump link:
https://www.dropbox.com/home?preview=local_dump.txt
Working device(remote) dump link:
https://www.dropbox.com/home?preview=working_device_dump.txt
Not working device(remote) dump link:
https://www.dropbox.com/home?preview=not_working_dump.txt
Javascript is attached below:
I traversed a number of stackoverflow posts and my JS should be up-to-date. I am guessing the codecs are making the stream fail but I don't know what to fix.
// get DOM elements
var dataChannelLog = document.getElementById('data-channel'),
iceConnectionLog = document.getElementById('ice-connection-state'),
iceGatheringLog = document.getElementById('ice-gathering-state'),
signalingLog = document.getElementById('signaling-state');
// peer connection
var pc = null;
// data channel
var dc = null, dcInterval = null;
function createPeerConnection() {
var config = {
sdpSemantics: 'unified-plan'
};
if (document.getElementById('use-stun').checked) {
config.iceServers = [{urls: ['stun:stun.l.google.com:19302']}];
}
var pc = new RTCPeerConnection(config);
// connect audio / video
pc.addEventListener('track', function(evt) {
if (evt.track.kind == 'video')
document.getElementById('video').srcObject = evt.streams[0];
else
document.getElementById('audio').srcObject = evt.streams[0];
});
return pc;
}
function negotiate() {
return pc.createOffer().then(function(offer) {
return pc.setLocalDescription(offer);
}).then(function() {
// wait for ICE gathering to complete
return new Promise(function(resolve) {
if (pc.iceGatheringState === 'complete') {
resolve();
} else {
function checkState() {
if (pc.iceGatheringState === 'complete') {
pc.removeEventListener('icegatheringstatechange', checkState);
resolve();
}
}
pc.addEventListener('icegatheringstatechange', checkState);
}
});
}).then(function() {
var offer = pc.localDescription;
var codec;
codec = document.getElementById('audio-codec').value;
// if (codec !== 'default') {
// offer.sdp = sdpFilterCodec('audio', codec, offer.sdp);
// }
//
// codec = document.getElementById('video-codec').value;
// if (codec !== 'default') {
// offer.sdp = sdpFilterCodec('video', codec, offer.sdp);
// }
document.getElementById('offer-sdp').textContent = offer.sdp;
console.log(offer);
return fetch('/offer', {
body: JSON.stringify({
sdp: offer.sdp,
type: offer.type,
video_transform: document.getElementById('video-transform').value
}),
headers: {
'Content-Type': 'application/json'
},
method: 'POST'
});
}).then(function(response) {
return response.json();
}).then(function(answer) {
document.getElementById('answer-sdp').textContent = answer.sdp;
return pc.setRemoteDescription(answer);
}).catch(function(e) {
/*
TODO: Presentation and logic mix a lot here (naturally). I don't think we need a framework (even though the
JS world has ALL OF THEM), but maybe we can group all presentation related things in separate functions,
for example change this to be catch(showConnectionError) and put the DOM logic inside
function showConnectionError(e) {...}?
*/
var el = document.querySelector('video');
var newEl = document.createElement('img');
newEl.src = '/working.png';
newEl.style.height = '100%'
el.parentNode.replaceChild(newEl, el);
});
}
function start() {
document.getElementById('start').style.display = 'none';
pc = createPeerConnection();
var time_start = null;
function current_stamp() {
if (time_start === null) {
time_start = new Date().getTime();
return 0;
} else {
return new Date().getTime() - time_start;
}
}
if (document.getElementById('use-datachannel').checked) {
var parameters = JSON.parse(document.getElementById('datachannel-parameters').value);
dc = pc.createDataChannel('chat', parameters);
dc.onclose = function() {
clearInterval(dcInterval);
dataChannelLog.textContent += '- close\n';
};
dc.onopen = function() {
dataChannelLog.textContent += '- open\n';
dcInterval = setInterval(function() {
var message = 'ping ' + current_stamp();
dataChannelLog.textContent += '> ' + message + '\n';
dc.send(message);
}, 1000);
};
dc.onmessage = function(evt) {
dataChannelLog.textContent += '< ' + evt.data + '\n';
if (evt.data.substring(0, 4) === 'pong') {
var elapsed_ms = current_stamp() - parseInt(evt.data.substring(5), 10);
dataChannelLog.textContent += ' RTT ' + elapsed_ms + ' ms\n';
}
};
}
var constraints = {
audio: document.getElementById('use-audio').checked,
video: false
};
if (document.getElementById('use-video').checked) {
var resolution = document.getElementById('video-resolution').value;
if (resolution) {
resolution = resolution.split('x');
constraints.video = {
width: parseInt(resolution[0], 0),
height: parseInt(resolution[1], 0)
};
} else {
constraints.video = true;
}
}
if (constraints.audio || constraints.video) {
if (constraints.video) {
document.getElementById('media').style.display = 'block';
}
navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
stream.getTracks().forEach(function(track) {
pc.addTrack(track, stream);
});
return negotiate();
/*
TODO: Can this also be promise-based? -> .catch(function(err) { ... })
*/
}, function(err) {
alert('Could not acquire media: ' + err);
});
} else {
negotiate();
}
document.getElementById('stop').style.display = 'inline-block';
}
function stop() {
document.getElementById('stop').style.display = 'none';
// close data channel
if (dc) {
dc.close();
}
// close transceivers
if (pc.getTransceivers) {
pc.getTransceivers().forEach(function(transceiver) {
if (transceiver.stop) {
transceiver.stop();
}
});
}
// close local audio / video
pc.getSenders().forEach(function(sender) {
sender.track.stop();
});
// close peer connection
setTimeout(function() {
pc.close();
}, 500);
}
function sdpFilterCodec(kind, codec, realSdp) {
var allowed = []
var rtxRegex = new RegExp('a=fmtp:(\\d+) apt=(\\d+)\r$');
var codecRegex = new RegExp('a=rtpmap:([0-9]+) ' + escapeRegExp(codec))
var videoRegex = new RegExp('(m=' + kind + ' .*?)( ([0-9]+))*\\s*$')
var lines = realSdp.split('\n');
var isKind = false;
for (var i = 0; i < lines.length; i++) {
if (lines[i].startsWith('m=' + kind + ' ')) {
isKind = true;
} else if (lines[i].startsWith('m=')) {
isKind = false;
}
if (isKind) {
var match = lines[i].match(codecRegex);
if (match) {
allowed.push(parseInt(match[1]));
}
match = lines[i].match(rtxRegex);
if (match && allowed.includes(parseInt(match[2]))) {
allowed.push(parseInt(match[1]));
}
}
}
var skipRegex = 'a=(fmtp|rtcp-fb|rtpmap):([0-9]+)';
var sdp = '';
isKind = false;
for (var i = 0; i < lines.length; i++) {
if (lines[i].startsWith('m=' + kind + ' ')) {
isKind = true;
} else if (lines[i].startsWith('m=')) {
isKind = false;
}
if (isKind) {
var skipMatch = lines[i].match(skipRegex);
if (skipMatch && !allowed.includes(parseInt(skipMatch[2]))) {
continue;
} else if (lines[i].match(videoRegex)) {
sdp += lines[i].replace(videoRegex, '$1 ' + allowed.join(' ')) + '\n';
} else {
sdp += lines[i] + '\n';
}
} else {
sdp += lines[i] + '\n';
}
}
return sdp;
}
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
I have some JavaScrip that is meant to check if there are any media tags selected or industry tags selected--this is so the portfolio items can be sorted and displayed accordingly in the browser.
What I have almost works 100%, but I can't figure out how to make it so that if only a media tag is selected or if only an industry tag is selected, the portfolio items should still be sorted accordingly. Currently, you have to select a media tag AND an industry tag, but I'd like users to be able to search using just a media tag OR just an industry tag.
Here is what I want to accomplish: If only a media tag is selected, then get all portfolio pieces that are associated with that media tag. If only an industry tag is selected, get all portfolio items that are associated with that industry tag. If a media tag AND industry tag are selected at the same time, get all portfolio items that are associated with BOTH.
Vanilla JS isn't my strong point so forgive me if this is a dumb question, but this has had me stumped for hours now.
No jQuery answers, please, as this whole page's functionality is built using JavaScript.
Here is the function:
var update = function () {
closeDrawer();
// update ui to reflect tag changes
// get our list of items to display
var itemsToDisplay = [];
var currentMediaTag = controlsContainer.querySelector('.media.selected');
var currentIndustryTag = controlsContainer.querySelector('.industry.selected');
if (currentMediaTag != "" && currentMediaTag != null) {
selectedMediaFilter = currentMediaTag.innerHTML;
}
if (currentIndustryTag != "" && currentIndustryTag != null) {
selectedIndustryFilter = currentIndustryTag.innerHTML;
}
if (selectedMediaFilter == "" && selectedIndustryFilter == "") {
itemsToDisplay = portfolioItems.filter(function (item) {
return item.preferred;
});
} else {
itemsToDisplay = portfolioItems.filter(function (item) {
var mediaTags = item.media_tags,
industryTags = item.industry_tags;
if(industryTags.indexOf(selectedIndustryFilter) < 0){
return false;
}
else if(mediaTags.indexOf(selectedMediaFilter) < 0){
return false;
}
else{
return true;
}
});
}
renderItems(itemsToDisplay);
}
Not entirely sure it's necessary but just in case, here is the complete JS file that handles the portfolio page:
(function ($) {
document.addEventListener("DOMContentLoaded", function (event) {
// for portfolio interaction
var portfolioGrid = (function () {
var gridSize = undefined,
parentContainer = document.querySelector('.portfolio-item-container');
containers = parentContainer.querySelectorAll('.view'),
drawer = parentContainer.querySelector('.drawer'),
bannerContainer = drawer.querySelector('.banner-container'),
thumbsContainer = drawer.querySelector('.thumbs-container'),
descriptionContainer = drawer.querySelector('.client-description'),
clientNameContainer = drawer.querySelector('.client-name'),
controlsContainer = document.querySelector('.portfolio-controls-container'),
selectedMediaFilter = "", selectedIndustryFilter = "";
var setGridSize = function () {
var windowSize = window.innerWidth,
previousGridSize = gridSize;
if (windowSize > 1800) {
gridSize = 5;
} else if (windowSize > 900) {
gridSize = 4;
} else if (windowSize > 600 && windowSize <= 900) {
gridSize = 3;
} else {
gridSize = 2;
}
if (previousGridSize != gridSize) {
closeDrawer();
}
};
var attachResize = function () {
window.onresize = function () {
setGridSize();
};
};
var getRowClicked = function (boxNumber) {
return Math.ceil(boxNumber / gridSize);
};
var getLeftSibling = function (row) {
var cI = row * gridSize;
return containers[cI >= containers.length ? containers.length - 1 : cI];
};
var openDrawer = function () {
drawer.className = 'drawer';
scrollToBanner();
};
var scrollToBanner = function () {
var mainContainer = document.querySelector('#main-container'),
mainBounding = mainContainer.getBoundingClientRect(),
scrollY = (drawer.offsetTop - mainBounding.bottom) - 10,
currentTop = document.body.getBoundingClientRect().top;
animate(document.body, "scrollTop", "", document.body.scrollTop, scrollY, 200, true);
};
var animate = function (elem, style, unit, from, to, time, prop) {
if (!elem) return;
var start = new Date().getTime(),
timer = setInterval(function () {
var step = Math.min(1, (new Date().getTime() - start) / time);
if (prop) {
elem[style] = (from + step * (to - from)) + unit;
} else {
elem.style[style] = (from + step * (to - from)) + unit;
}
if (step == 1) clearInterval(timer);
}, 25);
elem.style[style] = from + unit;
}
var closeDrawer = function () {
drawer.className = 'drawer hidden';
};
var cleanDrawer = function () {
bannerContainer.innerHTML = "";
clientNameContainer.innerHTML = "";
descriptionContainer.innerHTML = "";
thumbsContainer.innerHTML = "";
};
var resetThumbs = function () {
Array.prototype.forEach.call(thumbsContainer.querySelectorAll('.thumb'), function (t) {
t.className = "thumb";
});
};
var handleBannerItem = function (item) {
bannerContainer.innerHTML = "";
if (item.youtube) {
var videoContainer = document.createElement('div'),
iframe = document.createElement('iframe');
videoContainer.className = "videowrapper";
iframe.className = "youtube-video";
iframe.src = "https://youtube.com/embed/" + item.youtube;
videoContainer.appendChild(iframe);
bannerContainer.appendChild(videoContainer);
} else if (item.soundcloud) {
var iframe = document.createElement('iframe');
iframe.src = item.soundcloud;
iframe.className = "soundcloud-embed";
bannerContainer.appendChild(iframe);
} else if (item.banner) {
var bannerImage = document.createElement('img');
bannerImage.src = item.banner;
bannerContainer.appendChild(bannerImage);
}
};
var attachClick = function () {
Array.prototype.forEach.call(containers, function (n, i) {
n.querySelector('a.info').addEventListener('click', function (e) {
e.preventDefault();
});
n.addEventListener('click', function (e) {
var boxNumber = i + 1,
row = getRowClicked(boxNumber);
var containerIndex = row * gridSize;
if (containerIndex >= containers.length) {
// we're inserting drawer at the end
parentContainer.appendChild(drawer);
} else {
// we're inserting drawer in the middle somewhere
var leftSiblingNode = getLeftSibling(row);
leftSiblingNode.parentNode.insertBefore(drawer, leftSiblingNode);
}
// populate
cleanDrawer();
var mediaFilterSelected = document.querySelector('.media-tags .tag-container .selected');
var selectedFilters = "";
if (mediaFilterSelected != "" && mediaFilterSelected != null) {
selectedFilters = mediaFilterSelected.innerHTML;
}
var portfolioItemName = '';
var selectedID = this.getAttribute('data-portfolio-item-id');
var data = portfolioItems.filter(function (item) {
portfolioItemName = item.name;
return item.id === selectedID;
})[0];
clientNameContainer.innerHTML = data.name;
descriptionContainer.innerHTML = data.description;
var childItems = data.child_items;
//We will group the child items by media tag and target the unique instance from each group to get the right main banner
Array.prototype.groupBy = function (prop) {
return this.reduce(function (groups, item) {
var val = item[prop];
groups[val] = groups[val] || [];
groups[val].push(item);
return groups;
}, {});
}
var byTag = childItems.groupBy('media_tags');
if (childItems.length > 0) {
handleBannerItem(childItems[0]);
var byTagValues = Object.values(byTag);
byTagValues.forEach(function (tagValue) {
for (var t = 0; t < tagValue.length; t++) {
if (tagValue[t].media_tags == selectedFilters) {
handleBannerItem(tagValue[0]);
}
}
});
childItems.forEach(function (item, i) {
var img = document.createElement('img'),
container = document.createElement('div'),
label = document.createElement('p');
container.appendChild(img);
var mediaTags = item.media_tags;
container.className = "thumb";
label.className = "childLabelInactive thumbLbl";
thumbsContainer.appendChild(container);
if (selectedFilters.length > 0 && mediaTags.length > 0) {
for (var x = 0; x < mediaTags.length; x++) {
if (mediaTags[x] == selectedFilters) {
container.className = "thumb active";
label.className = "childLabel thumbLbl";
}
}
}
else {
container.className = i == 0 ? "thumb active" : "thumb";
}
img.src = item.thumb;
if (item.media_tags != 0 && item.media_tags != null) {
childMediaTags = item.media_tags;
childMediaTags.forEach(function (cMTag) {
varLabelTxt = document.createTextNode(cMTag);
container.appendChild(label);
label.appendChild(varLabelTxt);
});
}
img.addEventListener('click', function (e) {
scrollToBanner();
resetThumbs();
handleBannerItem(item);
container.className = "thumb active";
});
});
}
openDrawer();
});
});
};
var preloadImages = function () {
portfolioItems.forEach(function (item) {
var childItems = item.child_items;
childItems.forEach(function (child) {
(new Image()).src = child.banner;
(new Image()).src = child.thumb;
});
});
};
//////////////////////////////////// UPDATE FUNCTION /////////////////////////////////////
var update = function () {
closeDrawer();
// update ui to reflect tag changes
// get our list of items to display
var itemsToDisplay = [];
var currentMediaTag = controlsContainer.querySelector('.media.selected');
var currentIndustryTag = controlsContainer.querySelector('.industry.selected');
if (currentMediaTag != "" && currentMediaTag != null) {
selectedMediaFilter = currentMediaTag.innerHTML;
}
if (currentIndustryTag != "" && currentIndustryTag != null) {
selectedIndustryFilter = currentIndustryTag.innerHTML;
}
if (selectedMediaFilter == "" && selectedIndustryFilter == "") {
itemsToDisplay = portfolioItems.filter(function (item) {
return item.preferred;
});
} else {
itemsToDisplay = portfolioItems.filter(function (item) {
var mediaTags = item.media_tags,
industryTags = item.industry_tags;
if (industryTags.indexOf(selectedIndustryFilter) < 0) {
return false;
}
else if (mediaTags.indexOf(selectedMediaFilter) < 0) {
return false;
}
else {
return true;
}
});
}
renderItems(itemsToDisplay);
}
//////////////////////////////////// RENDERITEMS FUNCTION /////////////////////////////////////
var renderItems = function (items) {
var children = parentContainer.querySelectorAll('.view');
Array.prototype.forEach.call(children, function (child) {
// remove all event listeners then remove child
parentContainer.removeChild(child);
});
items.forEach(function (item) {
var container = document.createElement('div'),
thumb = document.createElement('img'),
mask = document.createElement('div'),
title = document.createElement('h6'),
excerpt = document.createElement('p'),
link = document.createElement('a');
container.className = "view view-tenth";
container.setAttribute('data-portfolio-item-id', item.id);
thumb.src = item.thumb;
mask.className = "mask";
title.innerHTML = item.name;
excerpt.innerHTML = item.excerpt;
link.href = "#";
link.className = "info";
link.innerHTML = "View Work";
container.appendChild(thumb);
container.appendChild(mask);
mask.appendChild(title);
mask.appendChild(excerpt);
mask.appendChild(link);
parentContainer.insertBefore(container, drawer);
});
containers = parentContainer.querySelectorAll('.view');
attachClick();
};
var filterHandler = function (linkNode, tagType) {
var prevSelection = document.querySelector("." + tagType + '.selected');
if (prevSelection != "" && prevSelection != null) {
prevSelection.className = tagType + ' tag';
}
linkNode.className = tagType + ' tag selected';
update();
};
var clearFilters = function (nodeList, filterType) {
Array.prototype.forEach.call(nodeList, function (node) {
node.className = filterType + " tag";
console.log("Clear filters function called");
});
}
var attachFilters = function () {
var mediaFilters = controlsContainer.querySelectorAll('.tag.media'),
industryFilters = controlsContainer.querySelectorAll('.tag.industry'),
filterToggle = controlsContainer.querySelectorAll('.filter-toggle');
// resets
controlsContainer.querySelector('.media-tags .reset')
.addEventListener('click',
function (e) {
e.preventDefault();
selectedMediaFilter = "";
clearFilters(controlsContainer.querySelectorAll('.media-tags a.tag'), "media");
update();
}
);
controlsContainer.querySelector('.industry-tags .reset')
.addEventListener('click',
function (e) {
e.preventDefault();
selectedIndustryFilter = "";
clearFilters(controlsContainer.querySelectorAll('.industry-tags a.tag'), "industry");
update();
}
);
Array.prototype.forEach.call(filterToggle, function (toggle) {
toggle.addEventListener('click', function (e) {
if (controlsContainer.className.indexOf('open') < 0) {
controlsContainer.className += ' open';
} else {
controlsContainer.className = controlsContainer.className.replace('open', '');
}
});
});
//Attaches a click event to each media tag "button"
Array.prototype.forEach.call(mediaFilters, function (filter) {
filter.addEventListener('click', function (e) {
e.preventDefault();
// var selectedMediaFilter = controlsContainer.querySelector('.media.selected');
//console.log("Media tag: " +this.innerHTML); *THIS WORKS*
filterHandler(this, "media");
});
});
Array.prototype.forEach.call(industryFilters, function (filter) {
filter.addEventListener('click', function (e) {
e.preventDefault();
// var selectedIndustryFilter = this.querySelector('.industry.selected');
// console.log("Industry tag: " +this.innerHTML); *THIS WORKS*
filterHandler(this, "industry");
});
});
};
return {
init: function () {
setGridSize();
attachResize();
attachClick();
preloadImages();
// portfolio page
if (controlsContainer) {
attachFilters();
}
}
};
})();
portfolioGrid.init();
});
}());
$ = jQuery.noConflict();
if(industryTags.indexOf(selectedIndustryFilter) < 0){
return false;
}
else if(mediaTags.indexOf(selectedMediaFilter) < 0){
return false;
}
That part is giving you headaches. Whenever no industry tag or media tag is selected this will exit the function.
Change to:
if(industryTags.indexOf(selectedIndustryFilter) < 0 && mediaTags.indexOf(selectedMediaFilter) < 0){
return false;
}
Now it will test if at least one tag is selected. If so then render items.
I made a change just to experiment with an idea, and this setup works:
if((selectedIndustryFilter !="" && industryTags.indexOf(selectedIndustryFilter) < 0) || (selectedMediaFilter !="" && mediaTags.indexOf(selectedMediaFilter) < 0)){
return false;
}
return true;
Not sure if it's the best solution ever but it seems to work and I'm not going to complain.
Honestly do not know whats happen, this was working this morning, have not changed a thing but now when i click my button to generate my images I get this error.
Can anyone tell me why and how to fix this please.
Error
test initMock test generate 1
TypeError: Cannot create property 'style' on string 'a'
at i._createCanvasElement (fabric.min.js:2)
at i._createLowerCanvas (fabric.min.js:2)
at i._initStatic (fabric.min.js:2)
at initialize (fabric.min.js:3)
at new i (fabric.min.js:1)
at b.$scope.uploadImage (controller.js:855)
at b.$scope.generate (controller.js:929)
at fn (eval at compile (angular.js:15500), <anonymous>:4:144)
at e (angular.js:27285)
at b.$eval (angular.js:18372)
my functions
$scope.uploadImage = function (where) {
var deferred = $q.defer();
if (where === 'upload') {
var f = document.getElementById('uploadCreative').files[0];
var r = new FileReader();
r.onload = function () {
var image = new Image();
image.src = r.result;
image.onload = function () {
$scope.resize(image.src).then(function (response) {
deferred.resolve(response);
console.log('hehe NO!');
console.log('hehe NO!');
}).catch(function (response) {
})
}
};
r.readAsDataURL(f);
}
if (where === 'local') {
function ax(a, callback) {
callback(localStorage.getItem(a));
}
var loadCanvas = new fabric.Canvas('a');
divHeight = $('.image-builder').height();
if ($scope.format === '1') {
Aratio = 0.67;
} else if ($scope.format === '2') {
Aratio = 0.56;
} else if ($scope.format === '3') {
divHeight = divHeight / 1.5;
Aratio = 2;
} else if ($scope.format === '4') {
Aratio = 0.67;
} else {
Aratio = 1
}
loadCanvas.setHeight(divHeight - 15);
loadCanvas.setWidth((divHeight - 15) * Aratio);
if (localStorage.getItem('backgroundImage') !== 'null') {
background = localStorage.getItem('backgroundImage');
var imgBc = new Image();
imgBc.onload = function () {
// this is syncronous
Iwidth = this.width;
Iheight = this.height;
var f_img = new fabric.Image(imgBc);
loadCanvas.setBackgroundImage(f_img, loadCanvas.renderAll.bind(loadCanvas), {
scaleY: loadCanvas.height / Iheight,
scaleX: loadCanvas.width / Iwidth
});
var test = ax('CC-canvas', function (response) {
loadCanvas.loadFromJSON(response, function () {
loadCanvas.renderAll();
$scope.resize(loadCanvas.toDataURL()).then(function (response) {
deferred.resolve(response);
}).catch(function (response) {
})
});
});
};
imgBc.src = background;
} else {
var test = ax('CC-canvas', function (response) {
loadCanvas.loadFromJSON(response, function () {
loadCanvas.renderAll();
$scope.resize(loadCanvas.toDataURL()).then(function (response) {
deferred.resolve(response);
}).catch(function (response) {
console.log(response);
})
});
});
}
}
return deferred.promise;
};
$scope.generate = function () {
$scope.generating = true;
$scope.generateBtn = 'Generating';
for (i = 0; i < $scope.gallery.length; i++) {
$scope.select[i] = '';
}
$scope.gallery = [];
$scope.checkPhoto = [];
console.log("test generate 1");
$scope.uploadImage($scope.creative).then(function (result) {
console.log("test generate 2");
$scope.generateCanvas(result, $scope.left, $scope.tops, $scope.wi, $scope.hi, $scope.per, $scope.btmR, $scope.btmL, $scope.backUrl)
.then(function () {
$timeout(function () {
//push final photo to array befor send to back end
$scope.photosToPhp.push(canvas2.toDataURL());
}, 800);
if ($scope.count < ($scope.photos[$scope.format].length - 1)) {
$scope.generate();
$scope.count++;
$scope.left = $scope.photos[$scope.format][$scope.count]['left'];
$scope.tops = $scope.photos[$scope.format][$scope.count]['tops'];
$scope.wi = $scope.photos[$scope.format][$scope.count]['wi'];
$scope.hi = $scope.photos[$scope.format][$scope.count]['hi'];
$scope.per = $scope.photos[$scope.format][$scope.count]['per'];
$scope.btmR = $scope.photos[$scope.format][$scope.count]['btmR'];
$scope.btmL = $scope.photos[$scope.format][$scope.count]['btmL'];
$scope.backUrl = "/mm3/public/img/formats/" + $scope.format + "/" + $scope.photos[$scope.format][$scope.count]['backUrl'];
$scope.$apply();
console.log("test generate 3");
} else {
//all photos've been pushed now sending it to back end
$timeout(function () {
// console.log($scope.photosToPhp[0]);
$http.post('/mm3/savePhoto', $scope.photosToPhp).then(function (success) {
$scope.generating = false;
$scope.generateBtn = 'Generate';
//creating mock up gallery
for (var x = 0; x < success.data.photos; x++) {
var file = '/mm3/tmp/' + success.data.folder + "/out" + x + ".png";
$scope.gallery.push(file);
}
$scope.photosToPhp = [];
}, function (error) {
});
}, 800);
$scope.count = 0;
$scope.left = $scope.photos[$scope.format][$scope.count]['left'];
$scope.tops = $scope.photos[$scope.format][$scope.count]['tops'];
$scope.wi = $scope.photos[$scope.format][$scope.count]['wi'];
$scope.hi = $scope.photos[$scope.format][$scope.count]['hi'];
$scope.per = $scope.photos[$scope.format][$scope.count]['per'];
$scope.btmR = $scope.photos[$scope.format][$scope.count]['btmR'];
$scope.btmL = $scope.photos[$scope.format][$scope.count]['btmL'];
$scope.backUrl = "/mm3/public/img/formats/" + $scope.format + "/" + $scope.photos[$scope.format][$scope.count]['backUrl'];
$scope.$apply();
}
console.log("test generate 4");
})
.catch(function (errorUrl) {
console.log(errorUrl);
})
})
};
Solved bu downgrading fabric js to 1.5 not 1.7 that i upgraded to, dont know why this worked but it dose
So this is a part of greasemonkey userscript. It's an adviser for an online game. At the end of it i've got this:
function do_login() {
// var loc = reg2.exec(document.location.href);
//Auto backing to login page
if (document.location.href.search("logout") != -1) {
window.setTimeout(function () {
document.location.href = "http://www" + gamepage;
}, 100);
}
else {
//login
try {
var logindata = explode(GM_getValue("logindata", "[]"));
}
catch (err) {
var logindata = new Array;
}
unsafeWindow.showDiv("login_div");
$("login_div").style.zIndex = "20";
$("login_div").getElementsByClassName("kh_btn")[0].addEventListener("click", function () {
var currServer = $("l_server").value;
var currUser = $("l_loginname").value.toLowerCase();
GM_setValue(lng + "_" + currServer + "_username", currUser);
}, false);
function submit_login(currUserNr) {
$("l_server").value = logindata[currUserNr][1];
$("l_loginname").value = logindata[currUserNr][2];
$("l_password").value = logindata[currUserNr][3];
$("login_div").getElementsByClassName("kh_btn")[0].click();
}
var newdiv = createElement("div", {style: "position:absolute;top:0px;left:0px;width:412px;padding:10px;background-color:#999;-moz-border-radius:10px;"}, $("login_div"));
for (var v = 0; v < logindata.length; v++) if (logindata[v][1] != "0") {
var newbutton = createElement("button", {type: "button", class: "cursorclickable", id: "autologin" + v, style: "width:200px;height:20px;margin:3px;"}, newdiv, texte["server"] + " " + logindata[v][1] + "." + logindata[v][0] + ": " + logindata[v][2]);
newbutton.addEventListener("click", function () {
submit_login(this.id.replace("autologin", ""));
}, false);
}
newdiv = null;
newbutton = null;
}
}
It's executed when script finds "logout" in the url.
Now, everything works, it's entering main-page, creating a button, the button itself works, but now i would like to execute "onlick" automatically.
You could select the element and then invoke the .click() method:
document.querySelector('#myElement')[0].click();
I'm using an S3Slider on WordPress. I'd like it to stop after one rotation, but can't seem to figure out the setting.
The following code is used in the slider.js file. Right now it's live at http://beaconwc.com on the frontpage, would like it to show the two slides and then stop until the user refreshes the page.
(function($){
$.fn.s3Slider = function(vars) {
var element = this;
var timeOut = (vars.timeOut != undefined) ? vars.timeOut : 4000;
var current = null;
var timeOutFn = null;
var faderStat = true;
var mOver = false;
var capOpacity = vars.captionOpacity || .7;
var items = $("#" + element[0].id + "Content ." + element[0].id + "Image");
var itemsSpan = $("#" + element[0].id + "Content ." + element[0].id + "Image div");
itemsSpan.css({
'opacity': capOpacity,
'display': 'none'
});
items.each(function(i) {
$(items[i]).mouseover(function() {
mOver = true;
});
$(items[i]).mouseout(function() {
mOver = false;
fadeElement(true);
});
});
var fadeElement = function(isMouseOut) {
var thisTimeOut = (isMouseOut) ? (timeOut/2) : timeOut;
thisTimeOut = (faderStat) ? 10 : thisTimeOut;
if(items.length > 0) {
timeOutFn = setTimeout(makeSlider, thisTimeOut);
} else {
console.log("Poof..");
}
}
var makeSlider = function() {
current = (current != null) ? current : items[(items.length-1)];
var currNo = jQuery.inArray(current, items) + 1
currNo = (currNo == items.length) ? 0 : (currNo - 1);
var newMargin = $(element).width() * currNo;
if(faderStat == true) {
if(!mOver) {
$(items[currNo]).fadeIn((timeOut/6), function() {
if($(itemsSpan[currNo]).css('bottom') == 0) {
$(itemsSpan[currNo]).slideUp((timeOut/6), function() {
faderStat = false;
current = items[currNo];
if(!mOver) {
fadeElement(false);
}
});
} else {
$(itemsSpan[currNo]).slideDown((timeOut/6), function() {
faderStat = false;
current = items[currNo];
if(!mOver) {
fadeElement(false);
}
});
}
});
}
} else {
if(!mOver) {
if($(itemsSpan[currNo]).css('bottom') == 0) {
$(itemsSpan[currNo]).slideDown((timeOut/6), function() {
$(items[currNo]).fadeOut((timeOut/6), function() {
faderStat = true;
current = items[(currNo+1)];
if(!mOver) {
fadeElement(false);
}
});
});
} else {
$(itemsSpan[currNo]).slideUp((timeOut/6), function() {
$(items[currNo]).fadeOut((timeOut/6), function() {
faderStat = true;
current = items[(currNo+1)];
if(!mOver) {
fadeElement(false);
}
});
});
}
}
}
}
makeSlider();
};
})(jQuery);
Thanks!
Source
http://www.serie3.info/s3slider/