﻿// ==UserScript==
// @name          quickPV
// @namespace     net.moeffju.dA
// @description	  AJAX policy violation filing
// @include       http://www.deviantart.com/view/*
// @include       http://www.deviantart.com/deviation/*
// @exclude       http://www.deviantart.com/deviation/*/favourites
// ==/UserScript==

// © 2005, 2006 Matthias Bauer <http://moeffju.deviantart.com/>

/* 
  Version 0.2
*/

var SCRIPT_NAME = 'quickPV';
var SCRIPT_VERSION = '0.2';

var ICON_CLOSE_URL = 'http://i.deviantart.com/icons/misc/x.gif';

function xpath(query, contextNode, resultType) {
  if (null == contextNode) contextNode = document;
  if (null == resultType) resultType = XPathResult.ORDERED_NODE_SNAPSHOT_TYPE;
  return document.evaluate(query, contextNode, null, resultType, null);
}

function xpath1(query, contextNode) {
  return xpath(query, contextNode, XPathResult.FIRST_ORDERED_NODE_TYPE).singleNodeValue;
}

function each(a,f) {
  var l=a.length;
  for (var i=0;i<l;i++){f(a[i]);}
}

function c(s){return document.createElement(s);}
function t(s){return document.createTextNode(s);}
function bt(s){var b=c('input');b.type='button';b.className='button';b.value=s;return b;}
function tf(s){var t=c('input');t.type='text';t.className='text';t.size=40;if(s)t.value=s;return t;}
function dt(s){var d=c('dt');d.appendChild(s);return d;}
function dd(s){var d=c('dd');d.appendChild(s);return d;}
function so(v,o){var d=c('select');for(var i=0;oo=o[i];i++){var e=c('option');e.textContent=oo;e.value=i;e.selected=(i==v);d.appendChild(e);}return d;}

function addBehavior() {
  var target = xpath1("id('artist-comments')/div[1]/a[last()]");
  
  if (! /Policy Violation/.test(target.textContent)) return;
  
  var a = c('a');
  a.className = 'h';
  a.textContent = 'quickPV';
  a.href = 'javascript:;';
  a.addEventListener('click', function(){ buttonClicked(); }, true);
  
  target.parentNode.appendChild(t(' / '));
  target.parentNode.appendChild(a);
}

function buttonClicked() {
  var self = this;
  if (self.disabled) return;
  var target = xpath1("id('artist-comments')").parentNode;
  
  var marker_url = 'URL (optional)';
  
  var h = c('div');
  var hdr = c('p');
  var btclose = c('img');
  var viotype = c('select');
  var viotypes = {
    0: 'Other',
    1: 'Wrong Section',
    2: 'Broke Section Rules',
    3: 'Preview Image Different',
    4: 'Ripped Artwork',
    5: 'Unauthorized Reuse',
    6: 'Inappropriate Nudity',
    7: 'Bigotry',
  };
  var viourl = tf(marker_url);
  var viobody = c('textarea');
  var hbt = c('div');
  var btok = bt('Send');
  var btcancel = bt('Cancel');
  
  hdr.innerHTML = '<strong>' + SCRIPT_NAME + '</strong>';
  hdr.style.paddingBottom = '3px';
  
  btclose.src = ICON_CLOSE_URL;
  btclose.style.cssFloat = 'right';
  
  viourl.style.display = 'block';
  viourl.style.visibility = 'hidden';
  viourl.addEventListener('focus', function() { if (viourl.value==marker_url) viourl.value = ''; }, false);
  viourl.addEventListener('blur',  function() { if (viourl.value=='') viourl.value = marker_url; }, false);
  
  for (var k in viotypes) {
    var o = c('option');
    o.value = k;
    o.textContent = viotypes[k];
    viotype.appendChild(o);
  }
  viotype.style.display = 'block';
  var f = function() { viourl.style.visibility = ( viotype.value == 4 || viotype.value == 5 ?'visible':'hidden'); };
  each(['change','keyup','blur'], function(x){ viotype.addEventListener(x, f, false); });
  
  viobody.style.width = '300px';
  
  var fnhide = function() { target.removeChild(h); self.disabled = false; };
  btok.addEventListener('click', function() {
    if (viourl.value==marker_url) viourl.value = '';
    
    btcancel.disabled = btok.disabled = true;
    btok.value = 'Sending...';
    sendRequest(viotype.value, viourl.value, viobody.value, function(r) {
      if (r.status == 200) {
        btok.value = 'Sent!';
        setTimeout(fnhide, 1500);
      } else {
        btcancel.disabled = btok.disabled = false;
        alert('There was an error sending your policy violation report!\nThe server replied: '+r.status+' '+r.statusText+'\n\nTry again in a few minutes.');
      }
    });
  }, false);
  btcancel.addEventListener('click', fnhide, false);
  btclose.addEventListener('click', fnhide, false);
  
  each([btok, t(' '), btcancel], function(x) { hbt.appendChild(x); });
  each([         hdr, viotype, viourl, viobody, hbt], function(x){ x.style.width = '290px'; x.style.margin = '2px auto'; });
  each([btclose, hdr, viotype, viourl, viobody, hbt], function(x){ h.appendChild(x); });
  
  h.style.zIndex = '100';
  h.style.width = '320px';
  h.style.position = 'absolute';
  h.style.padding = '4px';
  h.style.marginTop = '2px';
  h.style.right = '40px';
  h.style.backgroundColor = '#DEE8E5';
  h.style.border = '1px solid #9DB1B0';
  h.style.MozBorderRadius = '3px';
  
  self.disabled = true;
  target.appendChild(h);
}

function sendRequest(type, url, body, cb) {
  var action = document.location.href.replace(/\/(view|deviation)/, '/violation');

  var data = [
    'viotype=' + encodeURIComponent(type),
    'viourl='  + encodeURIComponent(url),
    'viobody=' + encodeURIComponent(body),
  ].join('&');
  
  GM_xmlhttpRequest({
    method: 'POST',
    url: action,
    headers: {
      'User-Agent': navigator.userAgent + ' Greasemonkey ('+SCRIPT_NAME+'/'+SCRIPT_VERSION+')',
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    data: data,
    onload: cb,
  });
}

addBehavior();
