Tagger 20071023 1507 - Moving alpha2 to RC - still no dragging
git-svn-id: file:///home/shish/svn/shimmie2/trunk@561 7f39781d-f577-437e-ae19-be835c7a54ca
This commit is contained in:
		
							parent
							
								
									bcb5eecc56
								
							
						
					
					
						commit
						5d273e6879
					
				| @ -1,93 +1,155 @@ | |||||||
| <?php | <?php | ||||||
| // Tagger - Advanced Tagging
 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | ||||||
| // Author: Artanis (Erik Youngren <artanis.00@gmail.com>)
 |  * Tagger - Advanced Tagging v2                                              * | ||||||
| // Do not remove this notice.
 |  * Author: Artanis (Erik Youngren <artanis.00@gmail.com>)                    * | ||||||
|  |  * Do not remove this notice.                                                * | ||||||
|  |  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||||||
| 
 | 
 | ||||||
| class tagger extends Extension { | class Tagger extends Extension { | ||||||
| 	var $theme; | 	var $theme; | ||||||
| 	 | 	 | ||||||
| 	public function receive_event ($event) { | 	public function receive_event ($event) { | ||||||
| 		if(is_null($this->theme)) | 		if(is_null($this->theme)) | ||||||
| 			$this->theme = get_theme_object("tagger", "taggerTheme");	 | 			$this->theme = get_theme_object("tagger", "taggerTheme"); | ||||||
| 			 | 			 | ||||||
| 		if(is_a($event,"InitExtEvent")) { | 		if(is_a($event,'DisplayingImageEvent')) { | ||||||
| 			global $config; | 			global $page, $config, $user; | ||||||
| 			if ($config->get_int("ext-tagger_tags-min") == -1) |  | ||||||
| 				$config->set_int("ext-tagger_tags-min",2); |  | ||||||
| 				 |  | ||||||
| 			if ($config->get_string("ext-tagger_clear-tagme") == -1) |  | ||||||
| 				$config->set_bool("ext-tagger_clear-tagme",false); |  | ||||||
| 				 |  | ||||||
| 			if ($config->get_string("ext-tagger_show-hidden") == -1) |  | ||||||
| 				$config->set_bool("ext-tagger_show-hidden",false); |  | ||||||
| 		} |  | ||||||
| 		 |  | ||||||
| 		if(is_a($event,"DisplayingImageEvent")) { |  | ||||||
| 			//show tagger box
 |  | ||||||
| 			global $database; |  | ||||||
| 			global $page; |  | ||||||
| 			global $config; |  | ||||||
| 			 | 			 | ||||||
| 			$base_href = $config->get_string('base_href'); | 			if($config->get_bool("tag_edit_anon") || ($user->id != $config->get_int("anon_id"))) | ||||||
| 			$tags_min = (isset($_GET['tagger_min']) && $_GET['tagger_min']>0)?$_GET['tagger_min']:$config->get_int('ext-tagger_tags-min',2); | 				$this->theme->build_tagger($page,$event); | ||||||
| 			$hidden = $config->get_string( |  | ||||||
| 				'ext-tagger_show-hidden','N')=='N' ? |  | ||||||
| 				" AND substring(tag,1,1) != '.' " : null; |  | ||||||
| 				 |  | ||||||
| 			$tags = $database->Execute(" |  | ||||||
| 				SELECT tag |  | ||||||
| 				FROM `tags` |  | ||||||
| 				WHERE count>=?{$hidden} |  | ||||||
| 				ORDER BY tag",array($tags_min));
 |  | ||||||
| 				 |  | ||||||
| 			$this->theme->build($page, $tags); |  | ||||||
| 			global $user; |  | ||||||
| 			if($tags->_numOfRows > 1000 && $user->is_admin()) { |  | ||||||
| 				$page->add_block( new Block ( |  | ||||||
| 					"Warning - ext/tagger", |  | ||||||
| 					"<h4>It is likely that Tagger will not function</h4>
 |  | ||||||
| 					Currently the javascript code chokes on large numbers of |  | ||||||
| 					tags. The tag list currently numbers |  | ||||||
| 					<b>{$tags->_numOfRows}</b>.<br/> |  | ||||||
| 					You can increase the minimum use requirement for the tag |  | ||||||
| 					list in the <a href='".make_link('setup')."'>Board Config</a> |  | ||||||
| 					to reduce the size of this list.<br/> |  | ||||||
| 					This is a limitation of the method in which Tagger operates. |  | ||||||
| 					I am working on a solution, I do not know when such a |  | ||||||
| 					solution will be ready.",
 |  | ||||||
| 					"main",0)); |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 		 |  | ||||||
| 		if(is_a($event,"PageRequestEvent")) { |  | ||||||
| 			if($event->page_name == "about" && $event->get_arg(0) == "tagger") { |  | ||||||
| 				global $page; |  | ||||||
| 				$this->theme->show_about($page); |  | ||||||
| 			} |  | ||||||
| 			if($event->page_name == "tagger") { |  | ||||||
| 				global $page; |  | ||||||
| //				$this->theme->configTagger($page);
 |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		 |  | ||||||
| 		if(is_a($event, 'UserBlockBuildingEvent')) { |  | ||||||
| 			if($event->user->is_admin()) { |  | ||||||
| //				$event->add_link("Tagger Config", make_link("tagger"));
 |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		 |  | ||||||
| 		if(is_a($event, 'SetupBuildingEvent')) { |  | ||||||
| 			$sb = new SetupBlock("Tagger - Power Tagging"); |  | ||||||
| 			$sb->add_bool_option("ext-tagger_show-hidden", "Show Hidden Tags"); |  | ||||||
| 			$sb->add_bool_option( |  | ||||||
| 				"ext-tagger_clear-tagme", |  | ||||||
| 				"<br/>Remove '<a href='".make_link("post/list/tagme/1")."'>tagme</a>' on use"); |  | ||||||
| 			$sb->add_int_option( |  | ||||||
| 				"ext-tagger_tags-min", |  | ||||||
| 				"<br/>Ignore tags used fewer than "); $sb->add_label("times."); |  | ||||||
| 			$event->panel->add_block($sb); |  | ||||||
| 			} |  | ||||||
| 	} | 	} | ||||||
| } | } if(isset($_GET['debug'])) add_event_listener( new tagger()); | ||||||
| add_event_listener( new tagger()); | 
 | ||||||
|  | // Tagger AJAX back-end
 | ||||||
|  | class TaggerXML extends Extension { | ||||||
|  | 	public function receive_event($event) { | ||||||
|  | 		if(is_a($event,'PageRequestEvent') | ||||||
|  | 			&& $event->page_name == "tagger" | ||||||
|  | 			&& $event->get_arg(0) == "tags") | ||||||
|  | 		{ | ||||||
|  | 			global $page; | ||||||
|  | 			 | ||||||
|  | 			//$match_tags = null;
 | ||||||
|  | 			//$image_tags = null;
 | ||||||
|  | 			$tags=null; | ||||||
|  | 			if (isset($_GET['s'])) { // tagger/tags[/...]?s=$string
 | ||||||
|  | 				// return matching tags in XML form
 | ||||||
|  | 				$tags = $this->match_tag_list($_GET['s']); | ||||||
|  | 			} else if($event->get_arg(1)) { // tagger/tags/$int
 | ||||||
|  | 				// return arg[1] AS image_id's tag list in XML form
 | ||||||
|  | 				$tags = $this->image_tag_list($event->get_arg(1)); | ||||||
|  | 			} | ||||||
|  | 			 | ||||||
|  | 			$xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n". | ||||||
|  | 			"<tags xmlns='http://www.w3.org/1999/xhtml'>". | ||||||
|  | 				$tags. | ||||||
|  | 			"</tags>"; | ||||||
|  | 			 | ||||||
|  | 			$page->set_mode("data"); | ||||||
|  | 			$page->set_type("text/xml"); | ||||||
|  | 			$page->set_data($xml); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	private function match_tag_list ($s) { | ||||||
|  | 		global $database, $config, $event; | ||||||
|  | 		 | ||||||
|  | 		$values = array(); | ||||||
|  | 		 | ||||||
|  | 		// Match
 | ||||||
|  | 		$p = strlen($s) == 1? " ":"\_"; | ||||||
|  | 		$sq = "%".$p.$s."%"; | ||||||
|  | 		$match = "concat(?,tag) LIKE ?"; | ||||||
|  | 		array_push($values,$p,$sq); | ||||||
|  | 		// Exclude
 | ||||||
|  | //		$exclude = $event->get_arg(1)? "AND NOT IN ".$this->image_tags($event->get_arg(1)) : null;
 | ||||||
|  | 		 | ||||||
|  | 		// Hidden Tags
 | ||||||
|  | 		$hidden = $config->get_string('ext-tagger_show-hidden','N')=='N' ? | ||||||
|  | 			"AND substring(tag,1,1) != '.'" : null; | ||||||
|  | 		 | ||||||
|  | 		$q_where = "WHERE {$match} {$hidden} AND count > 0"; | ||||||
|  | 		 | ||||||
|  | 		// FROM based on return count
 | ||||||
|  | 		$q_from = null; | ||||||
|  | 		$count = $this->count($q_where,$values); | ||||||
|  | 		if ($count > 60) { | ||||||
|  | 			$q_from = "FROM (SELECT * FROM `tags` {$q_where} ". | ||||||
|  | 				"ORDER BY count DESC LIMIT 0,30) AS `c_tags`"; | ||||||
|  | 			$q_where = null; | ||||||
|  | 			$count = array("max"=>$count); | ||||||
|  | 		} else { | ||||||
|  | 			$q_from = "FROM `tags`"; | ||||||
|  | 			$count = null; | ||||||
|  | 		} | ||||||
|  | 		 | ||||||
|  | 		$tags = $database->Execute(" | ||||||
|  | 			SELECT * | ||||||
|  | 			{$q_from} | ||||||
|  | 			{$q_where} | ||||||
|  | 			ORDER BY tag",
 | ||||||
|  | 			$values); | ||||||
|  | 		 | ||||||
|  | 		return $this->list_to_xml($tags,"search",$s,$count); | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	private function image_tag_list ($image_id) { | ||||||
|  | 		global $database; | ||||||
|  | 		$tags = $database->Execute(" | ||||||
|  | 			SELECT tags.* | ||||||
|  | 			FROM image_tags JOIN tags ON image_tags.tag_id = tags.id | ||||||
|  | 			WHERE image_id=? ORDER BY tag", array($image_id));
 | ||||||
|  | 		return $this->list_to_xml($tags,"image",$image_id); | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	private function list_to_xml ($tags,$type,$query,$misc=null) { | ||||||
|  | 		$r = $tags->_numOfRows; | ||||||
|  | 		 | ||||||
|  | 		$s_misc = ""; | ||||||
|  | 		if(!is_null($misc)) | ||||||
|  | 			foreach($misc as $attr => $val)	$s_misc .= " ".$attr."=\"".$val."\""; | ||||||
|  | 		 | ||||||
|  | 		$result = "<list id=\"$type\" query=\"$query\" rows=\"$r\"{$s_misc}>";
 | ||||||
|  | 		foreach($tags as $tag) { | ||||||
|  | 			$result .= $this->tag_to_xml($tag); | ||||||
|  | 		} | ||||||
|  | 		return $result."</list>"; | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	private function tag_to_xml ($tag) { | ||||||
|  | 		return | ||||||
|  | 			"<tag  ". | ||||||
|  | 				"id=\"".$tag['id']."\" ". | ||||||
|  | 				"count=\"".$tag['count']."\">". | ||||||
|  | 				html_escape($tag['tag']). | ||||||
|  | 				"</tag>"; | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	private function count($query,$values) { | ||||||
|  | 		global $database; | ||||||
|  | 		return $database->Execute( | ||||||
|  | 			"SELECT COUNT(*) FROM `tags` $query",$values)->fields['COUNT(*)']; | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	private function image_tags ($image_id) { | ||||||
|  | 		global $database; | ||||||
|  | 		$list = "("; | ||||||
|  | 		$i_tags = $database->Execute( | ||||||
|  | 			"SELECT tag_id FROM `image_tags` WHERE image_id=?", | ||||||
|  | 			array($image_id)); | ||||||
|  | 
 | ||||||
|  | 		$b = false; | ||||||
|  | 		foreach($i_tags as $tag) { | ||||||
|  | 			if($b) | ||||||
|  | 				$list .= ","; | ||||||
|  | 			$b = true; | ||||||
|  | 			$list .= $tag['tag_id']; | ||||||
|  | 			 | ||||||
|  | 		} | ||||||
|  | 		$list .= ")"; | ||||||
|  | 		 | ||||||
|  | 		return $list; | ||||||
|  | 	} | ||||||
|  | } add_event_listener( new taggerXML(),10); | ||||||
| ?>
 | ?>
 | ||||||
|  | |||||||
| @ -1,210 +1,205 @@ | |||||||
| // Tagger - Advanced Tagging
 |  | ||||||
| // Author: Artanis (Erik Youngren <artanis.00@gmail.com>)
 |  | ||||||
| // Do not remove this notice.
 |  | ||||||
| // All other code copyright by their authors, see comments for details.
 |  | ||||||
| 
 |  | ||||||
| /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ | ||||||
| *                              Tagger Management                              * | * Tagger - Advanced Tagging v2                                                * | ||||||
| \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | * Author: Artanis (Erik Youngren <artanis.00@gmail.com>)                      * | ||||||
| // Global settings and oft-used objects
 | * Do not remove this notice.                                                  * | ||||||
| var remove_tagme = null; |  | ||||||
| var tags_field = false; |  | ||||||
| var set_button = false; |  | ||||||
| 
 |  | ||||||
| // Put everything in a class? better?
 |  | ||||||
| 
 |  | ||||||
| function taggerInit() { |  | ||||||
| 	// get imgdata hooks
 |  | ||||||
| 	tags_field = getTagsField(); |  | ||||||
| 	set_button = getSetButton(); |  | ||||||
| 
 |  | ||||||
| 	// Set up Tagger
 |  | ||||||
| 	// Get last position
 |  | ||||||
| 	c = getCookie('shimmie-tagger-position'); |  | ||||||
| 	c = c ? c.replace(/px/g,"").split(" ") : new Array(null,null); |  | ||||||
| 	taggerResetPos(c[0],c[1]); |  | ||||||
| 	 |  | ||||||
| 	tagger_tagIndicators(); |  | ||||||
| 	DragHandler.attach(byId("tagger_titlebar")); |  | ||||||
| 	remove_tagme = byId('tagme'); |  | ||||||
| 	 |  | ||||||
| 	// save position cookie on unload.
 |  | ||||||
| 	window.onunload = function(e) { |  | ||||||
| 		taggerSavePosition(); |  | ||||||
| 	}; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function taggerResetPos(x,y) { |  | ||||||
| 	tagger = byId("tagger_window"); |  | ||||||
| 
 |  | ||||||
| 	var pos = new Array(); |  | ||||||
| 	if(!x || !y) { |  | ||||||
| 		tagger.style.top=""; |  | ||||||
| 		tagger.style.left=""; |  | ||||||
| 		tagger.style.right="25px"; |  | ||||||
| 		tagger.style.bottom="25px"; |  | ||||||
| 		// get location in (left,top) terms
 |  | ||||||
| 		pos = findPos(tagger); |  | ||||||
| 	} else { |  | ||||||
| 		pos[0] = x; |  | ||||||
| 		pos[1] = y; |  | ||||||
| 	} |  | ||||||
| 	 |  | ||||||
| 	tagger.style.top = pos[1]+"px"; |  | ||||||
| 	tagger.style.left = pos[0]+"px"; |  | ||||||
| 	tagger.style.right=""; |  | ||||||
| 	tagger.style.bottom=""; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function taggerSavePosition() { |  | ||||||
| 	tw = byId('tagger_window'); |  | ||||||
| 	if (tw) { |  | ||||||
| 		xy = tw.style.left +" "+ tw.style.top |  | ||||||
| 		setCookie('shimmie-tagger-position',xy); |  | ||||||
| 		return true; |  | ||||||
| 	} |  | ||||||
| 	return false; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function tagger_tagIndicators() { |  | ||||||
| 	arObjTags = getElementsByTagNames('a',byId('tagger_body')); |  | ||||||
| 	 |  | ||||||
| 	for (i in arObjTags) { |  | ||||||
| 		objTag = arObjTags[i]; |  | ||||||
| 		if(tagExists(objTag)) { |  | ||||||
| 			objTag.style.fontWeight="bold"; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ |  | ||||||
| *                                   Tagging                                   * |  | ||||||
| \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||||||
| 
 | 
 | ||||||
| function toggleTag(objTag) { | /* Tagger Window Object | ||||||
| 	if(!tagExists(objTag)) { |  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||||||
| 		addTag(objTag); | function Tagger() { | ||||||
| 		if (remove_tagme && objTag.getAttribute('tag') != 'tagme') { | // components
 | ||||||
| 			remTag(remove_tagme); | 	this.t_parent  = null; | ||||||
| 		} | 	this.t_title   = null; | ||||||
| 	} else { | 	this.t_toolbar = null; | ||||||
| 		remTag(objTag); | 	this.t_menu    = null; | ||||||
| 	} | 	this.t_body    = null; | ||||||
| 	t = byId("tagger_new-tag"); | 	this.t_tags    = null; | ||||||
| 	if(t.value) { t.select(); } | 	this.t_form    = null; | ||||||
| } | 	this.t_status  = null; | ||||||
| 
 | // data
 | ||||||
| function addTag (objTag) {	 | 	this.searchTags  = null; | ||||||
| 	delim = tags_field.value==" "?"":" "; | 	this.appliedTags = null; | ||||||
| 
 | // methods
 | ||||||
| 	tags_field.value += delim + objTag.getAttribute('tag'); | 	this.initialize     = initialize; | ||||||
|  | 	this.submit         = submit; | ||||||
|  | 	this.tagSearch      = tagSearch; | ||||||
|  | 	this.searchRequest  = searchRequest; | ||||||
|  | 	this.searchReceive  = searchReceive; | ||||||
|  | 	this.tagListReceive = tagListReceive; | ||||||
|  | 	this.tagPublish     = tagPublish; | ||||||
|  | 	this.prepTags       = prepTags; | ||||||
|  | 	this.createTag      = createTag; | ||||||
|  | 	this.buildPages     = buildPages; | ||||||
|  | 	this.tagsToString   = tagsToString; | ||||||
|  | 	this.toggleTag      = toggleTag; | ||||||
|  | 	this.setAlert       = setAlert; | ||||||
| 	 | 	 | ||||||
| 	if(objTag.value != 'Add') { | // definitions
 | ||||||
| 		objTag.style.fontWeight = "bold"; | 	function initialize () { | ||||||
|  | 	// components
 | ||||||
|  | 		this.t_parent  = document.getElementById("tagger_parent"); | ||||||
|  | 		this.t_title   = document.getElementById("tagger_titlebar"); | ||||||
|  | 		this.t_toolbar = document.getElementById("tagger_toolbar"); | ||||||
|  | 		this.t_menu    = document.getElementById("tagger_p-menu"); | ||||||
|  | 		this.t_body    = document.getElementById("tagger_body"); | ||||||
|  | 		this.t_tags    = document.getElementById("tagger_tags"); | ||||||
|  | 		this.t_form    = this.t_tags.parentNode; | ||||||
|  | 		this.t_status  = document.getElementById("tagger_statusbar"); | ||||||
|  | 	//pages
 | ||||||
|  | 		//this.buildPages();
 | ||||||
|  | 	// initial data
 | ||||||
|  | 		ajaxXML(query+"/"+image_id,tagListReceive); | ||||||
|  | 	// reveal
 | ||||||
|  | 		this.t_parent.style.display = ""; | ||||||
| 	} | 	} | ||||||
| } | 	function submit() { | ||||||
|  | 		this.t_tags.value = Tagger.tagsToString(Tagger.appliedTags); | ||||||
|  | 	} | ||||||
|  | 	function tagSearch(s,ms) { | ||||||
|  | 		clearTimeout(tagger_filter_timer); | ||||||
|  | 		tagger_filter_timer = setTimeout("Tagger.searchRequest('"+s+"')",ms); | ||||||
|  | 	} | ||||||
|  | 	function searchRequest(s) { | ||||||
|  | 		var s_query = !s? query+"?s" : query+"?s="+sqlescape(s); | ||||||
| 
 | 
 | ||||||
| function remTag (objTag) {	 | 		if(!this.searchTags) { | ||||||
| 	aTags = tags_field.value.split(" "); | 			ajaxXML(s_query,searchReceive); | ||||||
| 	 | 			return true; | ||||||
| 	tags_field.value=""; | 		} else { | ||||||
| 	for(i in aTags) { | 			var prv_s = this.searchTags.getAttribute('query'); | ||||||
| 		aTag = aTags[i]; | 		 | ||||||
| 		if(aTag != objTag.getAttribute('tag')) { | 			if(s==prv_s) { | ||||||
| 			if(tags_field.value=="") { | 				return false; | ||||||
| 				tags_field.value += aTag; | 			}else if(!s || s.length <= 2 || s.length<prv_s.length || | ||||||
| 			} else { | 				this.searchTags.getAttribute("max")) | ||||||
| 				tags_field.value += " "+aTag; | 			{ | ||||||
|  | 				ajaxXML(s_query,searchReceive); | ||||||
|  | 				return true; | ||||||
|  | 				 | ||||||
|  | 			} else if(s.length > 2 && s.match(reescape(prv_s))) { | ||||||
|  | 				var len = this.searchTags.childNodes.length; | ||||||
|  | 				 | ||||||
|  | 				for (var i=len-1; i>=0; i--) { | ||||||
|  | 					var tag = this.searchTags.childNodes[i]; | ||||||
|  | 					var t_name = tag.firstChild.data; | ||||||
|  | 					 | ||||||
|  | 					if(!t_name.match(reescape(s))) { | ||||||
|  | 						this.searchTags.removeChild(tag); | ||||||
|  | 						// TODO: Fix so back searches are not needlessly re-queried.
 | ||||||
|  | 						//tag.setAttribute("style","display:none;");
 | ||||||
|  | 					} else { | ||||||
|  | 						//tag.setAttribute("style","");
 | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				 | ||||||
|  | 				if (len != this.searchTags.childNodes.length) { | ||||||
|  | 					this.searchTags.setAttribute('query',s); | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 		return false; | ||||||
| 	} | 	} | ||||||
| 	if(objTag.value != 'Add') { | 	function searchReceive(xml) { | ||||||
| 		objTag.style.fontWeight = ""; | 		Tagger.searchTags = document.importNode(xml.getElementsByTagName("list")[0],true); | ||||||
| 	} | 		tagPublish(Tagger.searchTags,document.getElementById("tagger_p-search")); | ||||||
| } | 		 | ||||||
| 
 | 		if(Tagger.searchTags.getAttribute("max")) { | ||||||
| function tagExists(objTag) { | 			Tagger.setAlert("maxout","Limited to "+Tagger.searchTags.getAttribute("rows")+" of "+Tagger.searchTags.getAttribute("max")+" tags"); | ||||||
| 	return tags_field.value.match(reescape(objTag.getAttribute('tag'))); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ |  | ||||||
| *                                  Filtering                                  * |  | ||||||
| \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |  | ||||||
| 
 |  | ||||||
| function tagger_filter() { |  | ||||||
| 	var filter = byId('tagger_new-tag'); |  | ||||||
| 	var arObjTags = getElementsByTagNames('a',byId('tagger_body')); |  | ||||||
| 	var prepend = filter.value.length<2? " ":"_"; |  | ||||||
| 	var search = prepend + reescape(filter.value); |  | ||||||
| 	 |  | ||||||
| 	for(i in arObjTags) { |  | ||||||
| 		objTag = arObjTags[i]; |  | ||||||
| 		tag = prepend + objTag.getAttribute('tag'); |  | ||||||
| 
 |  | ||||||
| 		if(tag.match(search) && taggerFilterMode(objTag)) { |  | ||||||
| 			objTag.style.display=''; |  | ||||||
| 		} else { | 		} else { | ||||||
| 			objTag.style.display='none'; | 			Tagger.setAlert("maxout",false); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } |  | ||||||
| function taggerToggleMode() { |  | ||||||
| 	var obj = byId('tagger_mode'); |  | ||||||
| 	 | 	 | ||||||
| 	if(obj.getAttribute('mode')=='all') { | 	function tagListReceive(xml) { | ||||||
| 		obj.setAttribute('mode', 'applied'); | 		Tagger.appliedTags = document.importNode(xml.getElementsByTagName("list")[0],true); | ||||||
| 		obj.innerHTML = 'View All Tags'; | 		tagPublish(Tagger.appliedTags,document.getElementById("tagger_p-applied")); | ||||||
| 	} else { |  | ||||||
| 		obj.setAttribute('mode','all'); |  | ||||||
| 		obj.innerHTML = 'View Applied Tags'; |  | ||||||
| 	} | 	} | ||||||
| 	tagger_filter(true); | 	function tagPublish(tag_list,page) { | ||||||
| } | 		page.innerHTML = ""; | ||||||
| function taggerFilterMode(objTag) { | 		Tagger.prepTags(tag_list); | ||||||
| 	var obj = byId('tagger_mode'); | 		page.appendChild(tag_list); | ||||||
| 	if(obj.getAttribute('mode') == 'all') { |  | ||||||
| 		return true; |  | ||||||
| 	} else { |  | ||||||
| 		return objTag.style.fontWeight=='bold'; |  | ||||||
| 	} | 	} | ||||||
| } | 	function prepTags(tag_list) { | ||||||
| 
 | 		var len = tag_list.childNodes.length; | ||||||
| /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ | 		 | ||||||
| *                                     Misc                                    * | 		for(var i=0; i<len;i++) { | ||||||
| \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | 			var tag = tag_list.childNodes[i]; | ||||||
| 
 | 			tag.onclick = function() { toggleTag(this); document.getElementById("tagger_filter").select(); }; | ||||||
| function getTagsField() { | 			tag.style.display="block"; | ||||||
| 	var nodes = getElementsByTagNames('input,textarea',byId('imgdata')); | 			tag.setAttribute("title",tag.getAttribute("count")+" uses"); | ||||||
| 	for (i in nodes) { | 		} | ||||||
| 		node = nodes[i]; | 	} | ||||||
| 		if (node.getAttribute('name') == 'tags') | 	function createTag(tag_name) { | ||||||
| 			return node; | 		if (tag_name.length>0) { | ||||||
| 	} | 			var tag = document.createElement("tag"); | ||||||
| 	return false; | 			tag.setAttribute("count","0"); | ||||||
| } | 			tag.setAttribute("id","newTag_"+tag_name); | ||||||
| 
 | 			tag.onclick = function() { toggleTag(this); }; | ||||||
| function pushSet(form_id) { | 			tag.appendChild(document.createTextNode(tag_name)); | ||||||
| 	if(set_button) { | 			Tagger.appliedTags.appendChild(tag); | ||||||
| 		set_button.click(); | 		} | ||||||
| 	} | 	} | ||||||
| } | 	function buildPages () { | ||||||
| 
 | 		var pages = getElementsByTagNames("div",document.getElementById("tagger_body")); | ||||||
| function getSetButton() { | 		var len = pages.length; | ||||||
| 	var form_nodes = getElementsByTagNames('input',byId('imgdata')); | 		for(var i=0; i<len; i++) { | ||||||
| 	for (i in form_nodes) { | 			this.t_menu.innerHTML += "<li onclick='Tagger.togglePages("+ | ||||||
| 		node = form_nodes[i]; | 				"\""+pages[i].getAttribute("id")+"\")'>"+ | ||||||
| 		if (node.getAttribute('value')=="Set" && node.getAttribute('type')=="submit") { | 				pages[i].getAttribute('name')+"</li>"; | ||||||
| 			return node; | 		} | ||||||
|  | 	} | ||||||
|  | 	function tagsToString(tags) { | ||||||
|  | 		var len = tags.childNodes.length; | ||||||
|  | 		var str = ""; | ||||||
|  | 		for (var i=0; i<len; i++) { | ||||||
|  | 			str += tags.childNodes[i].firstChild.data+" "; | ||||||
|  | 		} | ||||||
|  | 		return str; | ||||||
|  | 	} | ||||||
|  | 	function toggleTag(tag) { | ||||||
|  | 		if(tag.parentNode == Tagger.appliedTags) { | ||||||
|  | 			Tagger.appliedTags.removeChild(tag); | ||||||
|  | 		} else { | ||||||
|  | 			Tagger.appliedTags.appendChild(tag); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	function setAlert(type,arg) { | ||||||
|  | 		var alert = document.getElementById("tagger_alert_"+type); | ||||||
|  | 		if (alert) { | ||||||
|  | 			if (arg==false) { | ||||||
|  | 				//remove existing
 | ||||||
|  | 				alert.parentNode.removeChild(alert); | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  | 			//update prior
 | ||||||
|  | 			alert.innerHTML = arg; | ||||||
|  | 		} else if (arg!=false) { | ||||||
|  | 			//create
 | ||||||
|  | 			var status = document.createElement("div"); | ||||||
|  | 			status.setAttribute("id","tagger_alert_"+type); | ||||||
|  | 			status.innerHTML = arg; | ||||||
|  | 			Tagger.t_status.appendChild(status); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return false; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ | /* AJAX | ||||||
| *                                quirksmode.org                               * |  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||||||
| \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | function ajaxXML(url, callback) { | ||||||
|  | 	//var http = getHTTPObject();
 | ||||||
|  | 	var http = (new XMLHttpRequest() || new ActiveXObject("Microsoft.XMLHTTP")); | ||||||
|  | 	http.open("GET", url, true); | ||||||
|  | 	http.onreadystatechange = function() { | ||||||
|  | 		if(http.readyState == 4) callback(http.responseXML); | ||||||
|  | 	} | ||||||
|  | 	http.send(null); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| // http://www.quirksmode.org/dom/getElementsByTagNames.html
 | /* Miscellaneous Code | ||||||
|  |  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||||||
|  | 
 | ||||||
|  | // Quirksmode
 | ||||||
|  | // http://www.quirksmode.org/dom/getElementsByTagNames.htmlgetElementdocument.getElementById
 | ||||||
| function getElementsByTagNames(list,obj) { | function getElementsByTagNames(list,obj) { | ||||||
| 	if (!obj) var obj = document; | 	if (!obj) var obj = document; | ||||||
| 	var tagNames = list.split(','); | 	var tagNames = list.split(','); | ||||||
| @ -229,7 +224,6 @@ function getElementsByTagNames(list,obj) { | |||||||
| 	} | 	} | ||||||
| 	return resultArray; | 	return resultArray; | ||||||
| } | } | ||||||
| 
 |  | ||||||
| // http://www.quirksmode.org/js/findpos.html
 | // http://www.quirksmode.org/js/findpos.html
 | ||||||
| function findPos(obj) { | function findPos(obj) { | ||||||
| 	var curleft = curtop = 0; | 	var curleft = curtop = 0; | ||||||
| @ -264,3 +258,23 @@ function reescape(str){ | |||||||
| 	} | 	} | ||||||
| 	return ret | 	return ret | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // Modified from above
 | ||||||
|  | function sqlescape(str){ | ||||||
|  | 	var resp="#%&_" | ||||||
|  | 	var found=false | ||||||
|  | 	var ret="" | ||||||
|  | 	for(var i=0;i<str.length;i++) { | ||||||
|  | 		found=false | ||||||
|  | 		for(var j=0;j<resp.length;j++) { | ||||||
|  | 			if(str.charAt(i)==resp.charAt(j)) { | ||||||
|  | 				found=true;break | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if(found) { | ||||||
|  | 			ret+="\\" | ||||||
|  | 		} | ||||||
|  | 		ret+=str.charAt(i) | ||||||
|  | 	} | ||||||
|  | 	return ret | ||||||
|  | } | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | ||||||
|  * Tagger - Advanced Tagging                                                 * |  * Tagger - Advanced Tagging v2                                              * | ||||||
|  * Author: Artanis (Erik Youngren <artanis.00@gmail.com>)                    * |  * Author: Artanis (Erik Youngren <artanis.00@gmail.com>)                    * | ||||||
|  * Do not remove this notice.                                                * |  * Do not remove this notice.                                                * | ||||||
|  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||||||
| @ -8,65 +8,83 @@ | |||||||
| 	text-align:left; | 	text-align:left; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #tagger_window { | #tagger_parent { | ||||||
| 	position:fixed; | 	position:fixed; | ||||||
| 	text-align:left; | 	top:25px; | ||||||
| 	min-width:250px; | 	right:25px; | ||||||
|  | 	max-width:300px; | ||||||
|  | 
 | ||||||
| } | } | ||||||
|   | #tagger_parent * { | ||||||
|  | 	background-color:#EEE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #tagger_titlebar { | #tagger_titlebar { | ||||||
| 	background-color:#DDDDDD; | 	background-color:#ddd; | ||||||
| 	background-image:none; |  | ||||||
| 	border:2px solid; | 	border:2px solid; | ||||||
| 	cursor:move; | 	cursor:move; | ||||||
| 	font-weight:bold; | 	font-weight:bold; | ||||||
| 	/*margin-bottom:.5em;*/ | 	-moz-border-radius:5px 5px 0 0; | ||||||
| 	-moz-border-radius:2em 2em 0 0; |  | ||||||
| 	padding:.25em; | 	padding:.25em; | ||||||
| 	position:relative; |  | ||||||
| 	text-align:center; | 	text-align:center; | ||||||
| 	top:-0em; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #tagger_toolbar, #tagger_body { | ||||||
|  | 	padding:.25em; | ||||||
|  | 	border-style:solid; | ||||||
|  | 	border-width: 0px 2px 0px 2px;	 | ||||||
|  | } | ||||||
| #tagger_body { | #tagger_body { | ||||||
| 	background-color:#EEEEEE; | 	max-height:250px; | ||||||
| 	border:2px solid; | 	overflow:auto; | ||||||
| 	border-top:none; | 	overflow-x:hidden; | ||||||
| 	overflow:scroll; | 	overflow-y:auto; | ||||||
| 	padding:1em; |  | ||||||
| 	max-height:200px; |  | ||||||
| } | } | ||||||
| #tagger_filter { | 
 | ||||||
| 	background-color:#EEEEEE; | #tagger_statusbar { | ||||||
|  | 	background-color:#ddd; | ||||||
| 	border:2px solid; | 	border:2px solid; | ||||||
| 	border-bottom:none; | 	font-weight: bold; | ||||||
| 	border-top:none; | 	-moz-border-radius:0 0 5px 5px; | ||||||
| 	margin-bottom:-1px; | 	padding:.25em; | ||||||
| 	/*-moz-border-radius:1em 1em 0 0;*/ | } #tagger_statusbar * { background-color:#ddd; } | ||||||
| 	padding:1em; | 
 | ||||||
| 	padding-bottom:1px; | #tagger_body div { | ||||||
| 	text-align:center; | 	padding-bottom:.125em; | ||||||
|  | 	margin-bottom:.125em; | ||||||
|  | 	border-top:1px solid; | ||||||
| } | } | ||||||
| #tagger_filter input { | 
 | ||||||
|  | /* Tagger Styling | ||||||
|  |  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||||||
|  | #Tagger form { | ||||||
|  | 	display:inline; | ||||||
|  | } | ||||||
|  | #Tagger input { | ||||||
| 	width:auto; | 	width:auto; | ||||||
| } | } | ||||||
|  | #Tagger input[type=text] { | ||||||
|  | 	background-color:white; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| #tagger_body a { | /* Custom Element Base Styles | ||||||
|  |  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||||||
|  | 
 | ||||||
|  | list { | ||||||
|  | 	display:inherit; | ||||||
|  | } | ||||||
|  | tag { | ||||||
| 	font-size:1.25em; | 	font-size:1.25em; | ||||||
| 	display:block; | 	display:block; | ||||||
|  | } | ||||||
|  | tag:hover { | ||||||
| 	cursor:pointer; | 	cursor:pointer; | ||||||
|  | 	font-weight: bold; | ||||||
|  | 	background-color:#ddd; | ||||||
| } | } | ||||||
|  | list[id=image] tag:hover { | ||||||
| 
 | 
 | ||||||
| #Use #Tagger { |  | ||||||
| 	-moz-column-gap:20px; |  | ||||||
| 	-moz-column-count:3; |  | ||||||
| } | } | ||||||
|  | list[id=search] tag:hover { | ||||||
| 
 | 
 | ||||||
| #Use #Tagger li { |  | ||||||
| 	margin-bottom:1em; |  | ||||||
| 	max-width:30em; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #Tagger .tagger_js { |  | ||||||
| 	cursor:pointer; |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,198 +1,64 @@ | |||||||
| <?php | <?php | ||||||
| // Tagger - Advanced Tagging
 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | ||||||
| // Author: Artanis (Erik Youngren <artanis.00@gmail.com>)
 |  * Tagger - Advanced Tagging v2                                              * | ||||||
| // Do not remove this notice.
 |  * Author: Artanis (Erik Youngren <artanis.00@gmail.com>)                    * | ||||||
|  |  * Do not remove this notice.                                                * | ||||||
|  |  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||||||
| 
 | 
 | ||||||
| class taggerTheme extends Themelet { | class taggerTheme extends Themelet { | ||||||
| 
 | 	public function build_tagger ($page, $event) { | ||||||
| 	public function build($event,$tags) { | 		// Initialization code
 | ||||||
| 		// When overriding this function, take care that all tag attributes are
 | 		// TODO: AJAX test and fallback.
 | ||||||
| 		// maintained UNCHANGED. There are no attributes in the HTML code below
 | 		$page->add_block(new Block(null, | ||||||
| 		// that go unused by the javascript. If you fail to do this,
 | 			"<script type='text/javascript'>
 | ||||||
| 		// the extension will BREAK!
 | 				var query = '".make_link("tagger/tags")."'; | ||||||
| 		//
 | 				var image_id = ".$event->get_image()->id."; | ||||||
| 		// Now that that's sunk in, chaniging title attributes is fine.
 | 				var tagger_filter_timer = null; | ||||||
| 		global $config; | 				var Tagger = new Tagger(); | ||||||
| 		global $page; | 				Tagger.initialize(); | ||||||
| 		 | 			</script>","main",1000));
 | ||||||
| 		// set up data
 |  | ||||||
| 		$base_href = $config->get_string('base_href'); |  | ||||||
| 		$tagme     = $config->get_string( |  | ||||||
| 			'ext-tagger_clear-tagme','N')=="Y"? |  | ||||||
| 			"<input type='hidden' id='tagme' tag='tagme'></input>": |  | ||||||
| 			null; |  | ||||||
| 		$url_about = make_link("about/tagger"); |  | ||||||
| 		 |  | ||||||
| 		// build floater tags
 |  | ||||||
| 		$h_tags = ""; |  | ||||||
| 		foreach($tags as $tag) { |  | ||||||
| 			$h_tags .= $this->tag_to_html($tag); |  | ||||||
| 		} |  | ||||||
| 		 |  | ||||||
| 		$html = " |  | ||||||
| 		<div style='font-size:0.7em;'> |  | ||||||
| 			Collapse this block to hide Tagger |  | ||||||
| 		</div> |  | ||||||
| 		<a href='$url_about'>About Tagger</a> |  | ||||||
| 		<hr/> |  | ||||||
| 		<button onclick='taggerResetPos();' class='tagger_js'>Default Location</button>".
 |  | ||||||
| 		// Tagger Floater
 |  | ||||||
| 		"<div id='tagger_window'>
 |  | ||||||
| 			<div id='tagger_titlebar' title='Drag to move'>Tagger</div>			 |  | ||||||
| 			<div id='tagger_filter'> |  | ||||||
| 				<input type='text' id='tagger_new-tag' value='' size='12'  |  | ||||||
| 					onfocus='this.select();' onkeyup='tagger_filter();' |  | ||||||
| 					focus='' title='Type to search' > |  | ||||||
| 				</input> |  | ||||||
| 				<input type='button' value='Add' tag='' title='Add typed tag' |  | ||||||
| 					onclick=' |  | ||||||
| 						this.attributes.tag.value= |  | ||||||
| 							byId(\"tagger_new-tag\").value;
 |  | ||||||
| 						toggleTag(this);'> |  | ||||||
| 				</input> |  | ||||||
| 				<input type='button' value='Set' onclick='pushSet();' |  | ||||||
| 					title='Save tags'></input> |  | ||||||
| 				$tagme |  | ||||||
| 				<hr/> |  | ||||||
| 				<a id='tagger_mode' class='tagger_js' mode='all' |  | ||||||
| 					onclick='taggerToggleMode()'>View Applied Tags</a> | |  | ||||||
| 				<a onclick='tagger_tagIndicators(); tagger_filter(true);' |  | ||||||
| 					class='tagger_js' >Refresh Filter</a> |  | ||||||
| 			</div> |  | ||||||
| 			<div id='tagger_body'>$h_tags</div> |  | ||||||
| 			<img src='$base_href/ext/tagger/onload.gif'	style='display:none;' |  | ||||||
| 				onload='taggerInit();' /> |  | ||||||
| 		</div>";
 |  | ||||||
| 		 | 		 | ||||||
|  | 		// Tagger block
 | ||||||
| 		$page->add_block( new Block( | 		$page->add_block( new Block( | ||||||
| 			"Tagger", | 			"Tagger", | ||||||
| 			$html, | 			$this->html($event->get_image()), | ||||||
| 			"left")); | 			"main")); | ||||||
| 		$page->add_header( |  | ||||||
| 			"<script
 |  | ||||||
| 				src='$base_href/ext/tagger/webtoolkit.drag.js' |  | ||||||
| 				type='text/javascript'></script>");
 |  | ||||||
| 	} | 	} | ||||||
|  | 	private function html($image) { | ||||||
|  | 		$i_image_id = int_escape($image->id); | ||||||
|  | 		$h_source = html_escape($image->source); | ||||||
|  | 		if(isset($_GET['search'])) {$h_query = "search=".url_escape($_GET['search']);} | ||||||
|  | 		else {$h_query = "";} | ||||||
|  | 		 | ||||||
|  | 		$url_form = make_link("tag_edit/set"); | ||||||
|  | 		 | ||||||
|  | 		$html = <<< EOD | ||||||
|  | <div id="tagger_parent" style="display:none;"> | ||||||
|  | 	<div id="tagger_titlebar">Tagger</div> | ||||||
| 	 | 	 | ||||||
|  | 	<div id="tagger_toolbar"> | ||||||
|  | 		<input type="text" value="" id="tagger_filter" onkeyup="Tagger.tagSearch(this.value, 500);"></input> | ||||||
|  | 		<input type="button" value="Add" onclick="Tagger.createTag(byId('tagger_filter').value);"></input> | ||||||
|  | 		<form action="$url_form" method="POST" onsubmit="Tagger.submit();"> | ||||||
|  | 			<input type='hidden' name='image_id' value='$i_image_id' id="image_id"></input> | ||||||
|  | 			<input type='hidden' name='query' value='$h_query'></input> | ||||||
|  | 			<input type='hidden' name='source' value='$h_source'></input> | ||||||
|  | 			<input type="hidden" name="tags" value="" id="tagger_tags"></input> | ||||||
| 
 | 
 | ||||||
| 	final public function show_about ($event) { | 			<input type="submit" value="Set"></input> | ||||||
| 		// The about page for Tagger. No override. Feel free to CSS it, though.
 | 		</form> | ||||||
| 		global $page; | 		<!--<ul id="tagger_p-menu"></ul> | ||||||
| 		global $config; | 		<br style="clear:both;"/>--> | ||||||
| 		$base_href = $config->get_string('base_href'); | 	</div> | ||||||
| 		 |  | ||||||
| 		$script1 = "$base_href/ext/tagger/script.js"; |  | ||||||
| 		$script2 = "$base_href/ext/tagger/webtoolkit.drag.js"; |  | ||||||
| 		 |  | ||||||
| 		$html = str_replace("\"",""",str_replace("\'","'"," |  | ||||||
| 		<ul id='Tagger'> |  | ||||||
| 			<li> |  | ||||||
| 				If Tagger is in your way, click and drag it\'s title bar to move |  | ||||||
| 				it to a more convienient location. |  | ||||||
| 			<li> |  | ||||||
| 				Click the links to add the tag to the image\'s tag list, when |  | ||||||
| 				done, press	the Set button to save the tags. |  | ||||||
| 			</li> |  | ||||||
| 			<li> |  | ||||||
| 				<p>Tagger gets all the tags with 2 or more uses, so the list can |  | ||||||
| 				get quite large. If you are having trouble finding the tag you |  | ||||||
| 				are looking for, you can enter it into the box at the top and as |  | ||||||
| 				you type, Tagger will remove tags that do not match to aid your |  | ||||||
| 				search. Usually, you\'ll only need one or two letters to trim |  | ||||||
| 				the list down to the tag you are looking for. |  | ||||||
| 				</p> |  | ||||||
| 				<p>One letter filters will look only at the first letter of the |  | ||||||
| 				tag. Two or more letters will search the beginning of every |  | ||||||
| 				word in every tag. |  | ||||||
| 				</p> |  | ||||||
| 				<p>If the tag is not in the list, finish typing out the tag and |  | ||||||
| 				click \"Add\" to add the tag to the image\'s tag list.
 |  | ||||||
| 				</p> |  | ||||||
| 				<p>Tags must have two uses to appear in Tagger\'s list, so |  | ||||||
| 				you'll have to enter the tag for at least one other image for it |  | ||||||
| 				to show up. |  | ||||||
| 				</p> |  | ||||||
| 			</li> |  | ||||||
| 			<li><h4>Requirements</h4> |  | ||||||
| 				<p>Tagger requires javascript for its functionality. Sorry, but |  | ||||||
| 				there\'s no other way to accomplish the tag list |  | ||||||
| 				modifications. |  | ||||||
| 				</p> |  | ||||||
| 				<p>If you have javascript completely disabled, you will not be |  | ||||||
| 				able to use Tagger. |  | ||||||
| 				</p> |  | ||||||
| 				<p>Depending on your method of disabling javascript, you may be |  | ||||||
| 				able to whitelist scripts. The script files used by Tagger are |  | ||||||
| 				<a href='$script1'>script.js</a> and |  | ||||||
| 				<a href='$script2'>webtoolkit.drag.js</a>. |  | ||||||
| 				</p> |  | ||||||
| 			</li> |  | ||||||
| 		</ul>"));
 |  | ||||||
| 		 |  | ||||||
| 		$page->set_title("Shimmie - About / Tagger - Advanced Tagging"); |  | ||||||
| 		$page->set_heading("About / Tagger - Advanced Tagging"); |  | ||||||
| 		$page->add_block( new Block("Author", |  | ||||||
| 			"Artanis (Erik Youngren <artanis.00@gmail.com>)","main",0)); |  | ||||||
| 		$page->add_block( new Block("Use", $html,"main",1)); |  | ||||||
| 	} |  | ||||||
| 	 | 	 | ||||||
| 	function configTagger($page/*,$presets*/) { | 	<div id="tagger_body"> | ||||||
| 		$presets = array( | 		<div id="tagger_p-applied" name="Applied Tags"></div> | ||||||
| 			'test_set_01' => 'tag set 01', | 		<div id="tagger_p-search" name="Searched Tags"></div> | ||||||
| 			'test_set_02' => 'tag set 02', | 	</div> | ||||||
| 			'tsuryuya' => 'tsuryuya hair_green eyes_yellow suzumiya_haruhi_no_yuutsu', | 	<div id="tagger_statusbar"></div> | ||||||
| 			'suzumiya_haruhi' => 'suzumiya_haruhi hair_brown eyes_brown suzumiya_haruhi_no_yuutsu'); | </div> | ||||||
| 		 | EOD; | ||||||
| 		$html="<table>"; |  | ||||||
| 		$html .= "<tr><th>Set Name</th><th>Tags</th></tr>"; |  | ||||||
| 		foreach($presets as $keyname => $tags) { |  | ||||||
| 			$html .= "<tr><td>$keyname</td><td>$tags</td></tr>"; |  | ||||||
| 		} |  | ||||||
| 		$html .= "</table>"; |  | ||||||
| 		 |  | ||||||
| 			 |  | ||||||
| 		$page->set_title("Shimmie / Configure / Tagger"); |  | ||||||
| 		$page->set_heading("Configure / Tagger"); |  | ||||||
| 		$page->add_block( new Block("Tag Presets",$html,'main',0)); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	final function tag_to_html ($tag) { |  | ||||||
| 		// Important for script.js, no override. You can CSS this, though.
 |  | ||||||
| 		// If you must, remove the 'final' keyword, but MAKE SURE the entire <A>
 |  | ||||||
| 		// tag is COPIED TO THE NEW FUNCTION EXACTLY! If you fail to do this,
 |  | ||||||
| 		// the extension will BREAK!
 |  | ||||||
| 		$tag_name = $tag['tag']; |  | ||||||
| 		$tag_id = $this->tag_id($tag_name); |  | ||||||
| 		$stag = $this->trimTag($tag_name,20,"_"); |  | ||||||
| 		 |  | ||||||
| 		$html = " |  | ||||||
| 			<a id='$tag_id' title='Apply "$tag_name"' tag='$tag_name' |  | ||||||
| 				onclick='toggleTag(this)'>$stag</a>";
 |  | ||||||
| 		 |  | ||||||
| 		return $html; | 		return $html; | ||||||
| 	} | 	} | ||||||
| 	 |  | ||||||
| 	// Important for script.js, no override.
 |  | ||||||
| 	final function tag_id ($tag) { |  | ||||||
| 		$tag_id = ""; |  | ||||||
| 		$m=null; |  | ||||||
| 		for($i=0; $i < strlen($tag); $i++) { |  | ||||||
| 			$l = substr($tag,$i,1); |  | ||||||
| 			$m=null; |  | ||||||
| 			preg_match("[\pP]",$l,$m); |  | ||||||
| 			$tag_id .= !isset($m[0]) ? $l:"_"; |  | ||||||
| 		} |  | ||||||
| 		 |  | ||||||
| 		return trim(str_replace("__","_",$tag_id)," _"); |  | ||||||
| 	} |  | ||||||
| 	 |  | ||||||
| 	function trimTag($s,$len=80,$br=" ") { |  | ||||||
| 		if(strlen($s) > $len) { |  | ||||||
| 			$s = substr($s, 0,$len-1); |  | ||||||
| 			$s = substr($s,0, strrpos($s,$br))."..."; |  | ||||||
| 		} |  | ||||||
| 		return $s; |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 |  | ||||||
| ?>
 | ?>
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user