Obsidian Portal
Menu
Sign In / Create Account
JavaScript is currently disabled. Obsidian Portal has a lot of really cool features that use JavaScript. You should check them out. We think you'll have a much more enjoyable experience.
Home
Campaigns
Games Nearby
Plans
Community
Help
Resources
nWoD RELOADED!
Author:
Jp12x
Slug:
jp12x_splat
Type:
GameCharacter
System:
World of Darkness
DST Source Code
HTML Template
<div class="wrapper"> <div class="tab_bar"> <span class="tab" onclick="jp12x_splat_tabClick(this,'sheet');"> CHARACTER </span> <span class="tab" onclick="jp12x_splat_tabClick(this,'bio');"> BIOGRAPHY </span> </div> <div class="main page_sheet" style="display:block;"> <div class="page_head"> <div class="section_head"> <span class="name dsf dsf_name"></span> </div> <span class="align_right dsf dsf_type typev"></span> • <span class="align_left dsf dsf_campaign"></span> </div> <div class="section_head">ATTRIBUTES</div> <div class="section"> <div class="column column_spacing"> Strength<span class="readonly pipsRange_5 dsf dsf_strength"></span><br /> Dexterity<span class="readonly pipsRange_5 dsf dsf_dexterity"></span><br /> Stamina<span class="readonly pipsRange_5 dsf dsf_stamina"></span><br /> </div> <div class="column column_spacing"> Presence<span class="readonly pipsRange_5 dsf dsf_charisma"></span><br /> Manipulation<span class="readonly pipsRange_5 dsf dsf_manipulation"></span><br /> Composure<span class="readonly pipsRange_5 dsf dsf_appearance"></span><br /> </div> <div class="column"> Intelligence<span class="readonly pipsRange_5 dsf dsf_perception"></span><br /> Wits<span class="readonly pipsRange_5 dsf dsf_intelligence"></span><br /> Resolve<span class="readonly pipsRange_5 dsf dsf_wits"></span><br /> </div> </div> <div class="section_head">ABILITIES</div> <div class="section"> <div class="column column_spacing"> <u>Talents</u> (-1 unskilled) <a class="listAdd listAdd_small interface" title="Add Special Talent" onclick="jp12x_splat_getElementsByClassName ('list_abilities')[0].addItem();">+</a><br /> Athletics<span class="readonly pipsRange_5 dsf dsf_athletics"></span><br /> Brawl<span class="readonly pipsRange_5 dsf dsf_brawl"></span><br /> Drive<span class="readonly pipsRange_5 dsf dsf_drive"></span><br /> Firearms<span class="readonly pipsRange_5 dsf dsf_firearms"></span><br /> Larceny<span class="readonly pipsRange_5 dsf dsf_larceny"></span><br /> Stealth<span class="readonly pipsRange_5 dsf dsf_stealth"></span><br /> Survival<span class="readonly pipsRange_5 dsf dsf_survival"></span><br /> Weaponry<span class="readonly pipsRange_5 dsf dsf_weaponry"></span><br /> <div class="list_abilities listColumns_1"> <div class="template"> <div> <a class="listDelete interface" title="Delete this item">✘</a> <a class="listPromote interface" title="Move this item up">↑</a> <a class="listDemote interface" title="Move this item down">↓</a> <span class="dsf dsf_ability_type_ type10"></span><span class="readonly pipsRange_5 dsf dsf_ability_value_">0</span><br /> </div> </div> </div> </div> <div class="column column_spacing"> <u>Skills</u> (-1 unskilled) <a class="listAdd listAdd_small interface" title="Add Special Skill" onclick="jp12x_splat_getElementsByClassName('list_talents') [0].addItem();">+</a><br /> Animal Ken<span class="readonly pipsRange_5 dsf dsf_animalken"></span><br /> Empathy<span class="readonly pipsRange_5 dsf dsf_empathy"></span><br /> Expression<span class="readonly pipsRange_5 dsf dsf_expression"></span><br /> Intimidation<span class="readonly pipsRange_5 dsf dsf_intimidation"></span><br /> Persuasion<span class="readonly pipsRange_5 dsf dsf_persuasion"></span><br /> Socialize<span class="readonly pipsRange_5 dsf dsf_socialize"></span><br /> Streetwise<span class="readonly pipsRange_5 dsf dsf_streetwise"></span><br /> Subterfuge<span class="readonly pipsRange_5 dsf dsf_subterfuge"></span><br /> <div class="list_talents listColumns_1"> <div class="template"> <div> <a class="listDelete interface" title="Delete this item">✘</a> <a class="listPromote interface" title="Move this item up">↑</a> <a class="listDemote interface" title="Move this item down">↓</a> <span class="dsf dsf_talent_type_ type10"></span><span class="readonly pipsRange_5 dsf dsf_talent_value_">0</span><br /> </div> </div> </div> </div> <div class="column"> <u>Knowledges</u> (-3 unskilled) <a class="listAdd listAdd_small interface" title="Add Special Knowledge" onclick="jp12x_splat_getElementsByClassName ('list_knowledges')[0].addItem();">+</a><br /> Academics<span class="readonly pipsRange_5 dsf dsf_academics"></span><br /> Computer<span class="readonly pipsRange_5 dsf dsf_computer"></span><br /> Craft<span class="readonly pipsRange_5 dsf dsf_craft"></span><br /> Investigation<span class="readonly pipsRange_5 dsf dsf_investigation"></span><br /> Medicine<span class="readonly pipsRange_5 dsf dsf_medicine"></span><br /> Occult<span class="readonly pipsRange_5 dsf dsf_occult"></span><br /> Politics<span class="readonly pipsRange_5 dsf dsf_politics"></span><br /> Science<span class="readonly pipsRange_5 dsf dsf_science"></span><br /> <div class="list_knowledges listColumns_1"> <div class="template"> <div> <a class="listDelete interface" title="Delete this item">✘</a> <a class="listPromote interface" title="Move this item up">↑</a> <a class="listDemote interface" title="Move this item down">↓</a> <span class="dsf dsf_knowledge_type_ type10"></span><span class="readonly pipsRange_5 dsf dsf_knowledge_value_">0</span><br /> </div> </div> </div> </div> </div> <div class="section"> <div class="column column_spacing"> <div class="section_head">BACKGROUNDS<a class="listAdd interface" title="Add Background" onclick="jp12x_splat_getElementsByClassName('list_backgrounds')[0].addItem ();">+</a></div> <div class="list_backgrounds listColumns_1"> <div class="template"> <div> <a class="listDelete interface" title="Delete this item">✘</a> <a class="listPromote interface" title="Move this item up">↑</a> <a class="listDemote interface" title="Move this item down">↓</a> <span class="dsf type5 dsf dsf_backgrounds_type_"></span><span class="readonly pipsRange_5 dsf dsf_backgrounds_value_">0</span><br /> </div> </div> </div> </div> <div class="column"> <div class="section_head">MERITS & FLAWS<a class="listAdd interface" title="Add Merit or Flaw" onclick="jp12x_splat_getElementsByClassName('list_flaws')[0].addItem ();">+</a></div> <div class="list_flaws listColumns_1"> <div class="template"> <div> <a class="listDelete interface" title="Delete this item">✘</a> <a class="listPromote interface" title="Move this item up">↑</a> <a class="listDemote interface" title="Move this item down">↓</a> <span class="dsf dsf_flaw_ typef"></span><br /> </div> </div> </div> </div> <div class="column"> <div class="section_head">SPECIALTIES<a class="listAdd interface" title="Add Specialty" onclick="jp12x_splat_getElementsByClassName('list_specialties')[0].addItem ();">+</a></div> <div class="list_specialties listColumns_1"> <div class="template"> <div> <a class="listDelete interface" title="Delete this item">✘</a> <a class="listPromote interface" title="Move this item up">↑</a> <a class="listDemote interface" title="Move this item down">↓</a> <span class="dsf type5 dsf dsf_specialty_type_"></span><span class="readonly pipsRange_5 dsf dsf_specialty_value_">0</span><br /> </div> </div> </div> </div> </div> <div class="section"> <div class="column column_spacing"> <div class="section_head">MISCELLANEOUS</div> Willpower<span class="readonly pipsRange_10 dsf dsf_willpower"></span><br /> Current<span class="readonly pipsRange_10 dsf dsf_current_will"></span><br /> Health<span class="readonly pipsRange_10 dsf dsf_health"></span><br /> Current<span class="readonly pipsRange_10 dsf dsf_chealth"></span><br /> </div> <div class="column"> <div class="section_head">NUMINA<a class="listAdd interface" title="Add Numina" <div class="listAdd interface" title="Add Numina" onclick="jp12x_splat_getElementsByClassName('list_numina')[0].addItem ();">+</a></div> <div class="list_numina listColumns_1"> <div class="template"> <div> <a class="listDelete interface" title="Delete this item">✘</a> <a class="listPromote interface" title="Move this item up">↑</a> <a class="listDemote interface" title="Move this item down">↓</a> <span class="dsf type5 dsf dsf_numina_type_"></span><span class="readonly pipsRange_5 dsf dsf_numina_value_">0</span><br /> </div> </div> </div> </div> <div class="column"> <div class="section_head">-</div> Initiative: <span class="dsf dsf_initiative typer"></span><br /> Speed: <span class="dsf dsf_speed typer"></span><br /> Defence: <span class="dsf dsf_defense typer"></span><br /> Armor: <span class="dsf dsf_armor typer"></span><br /> Experience: <span class="dsf dsf_experiance typer"></span><br /> </div> </div> <div class="section_head">SPLAT TRAITS<a class="listAdd interface" title="Add Trait" onclick="jp12x_splat_getElementsByClassName('list_traits')[0].addItem ();">+</a></div> <div class="section"> <div class="list_traits listColumns_3"> <div class="template"> <div class="has_tooltip"> <a class="listDelete interface" title="Delete this item">✘</a> <a class="listPromote interface" title="Move this item up">↑</a> <a class="listDemote interface" title="Move this item down">↓</a> <span class="dsf type5 dsf dsf_traits_type_"></span><span class="readonly pipsRange_10 dsf dsf_traits_value_">0</span><br /> </div> </div> </div> </div> <div class="section_head">EQUIPMENT<a class="listAdd interface" title="Add Equipment" onclick="jp12x_splat_getElementsByClassName('list_equipment')[0].addItem ();">+</a></div> <div class="section"> <div class="list_equipment listColumns_3"> <div class="template"> <div class="has_tooltip"> <a class="listDelete interface" title="Delete this item">✘</a> <a class="listPromote interface" title="Move this item up">↑</a> <a class="listDemote interface" title="Move this item down">↓</a> <span class="dsf dsf_equipment_name_ typef"></span><br /> <span class="readonly area dsf dsf_equipment_tootip_ is_tooltip button_float"></span> </div> </div> </div> </div> <div class="section_head">ATTACKS<a class="listAdd interface" title="Add Attack" onclick="jp12x_splat_getElementsByClassName('list_attacks')[0].addItem();"> +</a></div> <div class="section" style="position:relative;"> <span class="typea" style="text- decoration:underline;margin-right:103px;">Weapon</span> <span class="typed" style="text- decoration:underline;">Difficulty</span> <span class="typed" style="text- decoration:underline;">Damage</span> <span class="typed" style="text- decoration:underline;">Range</span> <span class="typed" style="text- decoration:underline;">Rate</span> <span class="typed" style="text- decoration:underline;">Clip</span> <span class="typed" style="text- decoration:underline;">Conceal</span> <div class="list_attacks listColumns_1"> <div class="template"> <div style="position:relative;"> <a class="listDelete interface" title="Delete this item">✘</a> <a class="listPromote interface" title="Move this item up">↑</a> <a class="listDemote interface" title="Move this item down">↓</a> <span class="dsf typea dsf_attack_weapon_"></span> <span class="dsf typed dsf_attack_difficulty_" style="position:absolute;left:251px;top:0px;"></span> <span class="dsf typed dsf_attack_damage_" style="position:absolute;left:327px;top:0px;"></span> <span class="dsf typed dsf_attack_range_" style="position:absolute;left:403px;top:0px;"></span> <span class="dsf typed dsf_attack_rate_" style="position:absolute;left:479px;top:0px;"></span> <span class="dsf typed dsf_attack_clip_" style="position:absolute;left:555px;top:0px;"></span> <span class="dsf typed dsf_attack_conceal_" style="position:absolute;left:631px;top:0px;"></span> <br /> </div> </div> </div> </div> <div class="page_foot"> <div class="section_head"> </div> Character By <span class="align_right dsf dsf_player"></span> • Sheet By <span class="align_left dsf dsf_dst_author"></span> </div> </div> <div class="main page_bio" style="display:none;"> <div class="page_head"> <div class="section_head"> <span class="name dsf dsf_name"></span> </div> <span class="align_right dsf dsf_type typev"></span> • <span class="align_left dsf dsf_campaign"></span> </div> <div class="section_head">BIOGRAPHY</div> <div class="section section_bio"> <span class="portrait_holder"> <span class="portrait dsf dsf_avatar_image"></span> </span> <span class="dsf dsf_bio"></span> </div> <div class="section_head">APPEARANCE</div> <div class="section"> <span class="area motivation readonly dsf dsf_desc"></span> </div> <div class="section_head">VIRTUE</div> <div class="section"> <span class="area motivation dsf readonly dsf_nature"></span> </div> <div class="section_head">VICE</div> <div class="section"> <span class="area motivation dsf readonly dsf_demeanor"></span> </div> <div class="section_head">CONCEPT</div> <div class="section"> <span class="area motivation dsf readonly dsf_concept"></span> </div> <div class="section_head">GOALS<a class="listAdd interface" title="Add Goal" onclick="jp12x_splat_getElementsByClassName('list_goals')[0].addItem();"> +</a></div> <div class="section"> <div class="listColumns_1 list_goals"> <div class="template"> <div> <a class="listDelete interface" title="Delete this item">✘</a> <a class="listPromote interface" title="Move this item up">↑</a> <a class="listDemote interface" title="Move this item down">↓</a> <span class="typew dsf dsf_goal_"></span><br /> </div> </div> </div> </div> <div class="section_head">ALLIES & CONTACTS<a class="listAdd interface" title="Add Contact" onclick="jp12x_splat_getElementsByClassName('list_contacts') [0].addItem();">+</a></div> <div class="section"> <div class="list_contacts listColumns_3"> <div class="template"> <div class="has_tooltip"> <a class="listDelete interface" title="Delete this item">✘</a> <a class="listPromote interface" title="Move this item up">↑</a> <a class="listDemote interface" title="Move this item down">↓</a> <span class="dsf typef dsf dsf_contact_type_"></span><br /> <span class="readonly area dsf dsf_contact_tootip_ is_tooltip button_float"></span> </div> </div> </div> </div> <div class="page_foot"> <div class="section_head"> </div> Character By <span class="align_right dsf dsf_player"></span> • Sheet By <span class="align_left dsf dsf_dst_author"></span> </div> </div> </div>
CSS
/* Tiffy Input Styles */ div.ds_jp12x_splat form{ position:relative; } div.ds_jp12x_splat input { padding:0px 0px 0px 0px; margin:-1px 0px 0px -1px; font-family:palatino; font-size:8pt; color:#050505; } div.ds_jp12x_splat .tiffytable_submit{ position:absolute; right:-2px; top:-1px; height:18px; width:10px; } div.ds_jp12x_splat .tiffytable_submit_text { position:relative; top:-4px; left:-1px; font-size:9pt; color:#050505; } div.ds_jp12x_splat .type3{ display:inline-block; margin:0px 0px 1px 0px; height:16px; width:150px; } div.ds_jp12x_splat .type5{ display:inline-block; margin:0px 0px 1px 0px; height:16px; width:120px; } div.ds_jp12x_splat .type7{ display:inline-block; margin:0px 0px 1px 0px; height:16px; width:67px; } div.ds_jp12x_splat .type10{ display:inline-block; margin:0px 0px 1px 0px; height:16px; width:55px; } div.ds_jp12x_splat .typef{ display:inline-block; margin:0px 0px 1px 0px; height:16px; width:193px; } div.ds_jp12x_splat .typeq{ display:inline-block; margin:0px 0px 1px 0px; height:16px; width:576px; } div.ds_jp12x_splat .typew{ display:inline-block; margin:0px 0px 1px 0px; min-height:16px; width:673px; } div.ds_jp12x_splat .typer{ display:inline-block; margin:0px 0px 1px 0px; height:16px; float:right; width:123px; text-align:right; } div.ds_jp12x_splat .typed{ display:inline-block; margin:0px 0px 1px 5px; height:16px; width:68px; text-align:center; } div.ds_jp12x_splat .typea{ display:inline-block; margin:0px 0px 1px 0px; height:16px; width:142px; text-align:left; } div.ds_jp12x_splat .typev{ display:inline-block; margin:0px 0px 1px 0px; height:16px; } div.ds_jp12x_splat span.typev button{ right:1px; } div.editable .dsf{ cursor:pointer; } div.editable .dsf:hover{ color:#050505; } div.editable .dsf_bio:hover{ color:#050505; cursor:text; } /* Pips Interface Styles */ div.ds_jp12x_splat .pipsRange_3{ position:relative; z-index:2; float:right; top:3px; width:41px; padding:0px 0px 0px 0px; margin:0px 0px 0px 0px; } div.ds_jp12x_splat .pipsRange_5{ position:relative; z-index:2; float:right; top:3px; width:70px; padding:0px 0px 0px 0px; margin:0px 0px 0px 0px; } div.ds_jp12x_splat .pipsRange_10{ position:relative; z-index:2; float:right; top:3px; width:142px; padding:0px 0px 0px 0px; margin:0px 0px 0px 0px; } /* Checks Interface Styles */ div.ds_jp12x_splat .check{ position:relative; top:1px; margin:0px 3px 0px 0px; } /* List Interface Styles */ div.ds_jp12x_splat .listAdd{ float:right; cursor:pointer; text-decoration:none; color:#050505; background-color:rgba(0,0,0,0.15); border-radius:8px; padding:0px 2px 0px 4px; width:11px; } div.ds_jp12x_splat .listAdd_small{ font-size:12pt; position:relative; left:5px; } div.ds_jp12x_splat .listAdd:hover{ color:#050505; background-color:rgba(0,0,0,0.2); } div.ds_jp12x_splat .listDelete{ color:#1b110e; cursor:pointer; letter-spacing:-1px; text-decoration:none; } div.ds_jp12x_splat .listDelete:hover{ color:#5A5854; } div.ds_jp12x_splat .listPromote{ cursor:pointer; letter-spacing:-1px; text-decoration:none; color:#1b110e; } div.ds_jp12x_splat .listPromote:hover{ color:#5A5854; } div.ds_jp12x_splat .listDemote{ cursor:pointer; text-decoration:none; color:#1b110e; } div.ds_jp12x_splat .listDemote:hover{ color:#5A5854; } div.ds_jp12x_splat .template{ display:none; } div.ds_jp12x_splat .column{ width:227px; display:inline-block; vertical-align:top; } div.ds_jp12x_splat .half_sheet_column{ width:340px; display:inline-block; vertical-align:top; } div.ds_jp12x_splat .double_column{ width:454px; display:inline-block; vertical-align:top; } div.ds_jp12x_splat .column_spacing{ margin-right:9px; } /* Text Area Interface Styles */ div.ds_jp12x_splat .area{ font-family:palatino; font-size:9pt; color:#1b110e; margin:0px 0px 0px 0px; padding:1px 0px 1px 1px; position:absolute; } div.ds_jp12x_splat .area_submit{ position:absolute; height:16px; width:10px; color:#070; top:0px; right:0px; } div.ds_jp12x_splat .area_submit_text { position:relative; top:-5px; left:-1px; font-size:9pt; } div.editable .area:hover{ color:#5A5854; } /* Tooltip Interface Styles */ div.ds_jp12x_splat .has_tooltip{ position:relative; } div.ds_jp12x_splat .is_tooltip{ display:none; position:absolute; width:180px; min-height:50px; background-color:#9d988f; background-color:rgba(157,152,143,0.95); border-radius:4px; border-style:solid; border-width:1px; border-color:#1b110e; padding:2px 4px 2px 6px; z-index:5; left:0px; top:0px; } div.ds_jp12x_splat .tip_area{ position:relative; left:-4px; } /* Exalted Sheet Styles */ div.ds_jp12x_splat .wrapper{ position:relative; width:730px; } div.ds_jp12x_splat .main{ position:relative; width:708px; padding:0px 10px 80px 10px; margin:40px 0px 20px 0px; background-image:url('http://cdn.obsidianportal.com/assets/163631/Revenant2.png'); background-position:top left; background-repeat:no-repeat; background-color:#ada89f; border-style:solid; border-width:1px; border-color:#1b110e; font-family:palatino; font-size:8pt; font-variant:small-caps; line-height:17px; color:#050505; letter-spacing:1px; } div.ds_jp12x_splat .small_font{ font-family:palatino; font-size:6pt; font-variant:small-caps; line-height:17px; color:#050505; } div.ds_jp12x_splat .corner_top_left{ position:absolute; left:-7px; top:-7px; z-index:4; } div.ds_jp12x_splat .corner_top_right{ position:absolute; right:-7px; top:-7px; z-index:4; } div.ds_jp12x_splat .corner_bottom_left{ position:absolute; left:-7px; bottom:-7px; z-index:4; } div.ds_jp12x_splat .corner_bottom_right{ position:absolute; right:-7px; bottom:-7px; z-index:4; } div.ds_jp12x_splat .brass_bottom{ position:absolute; left:262px; bottom:-7px; z-index:4; } div.ds_jp12x_splat .section{ padding:0px 0px 5px 0px; margin:0px 0px 10px 1px; } div.ds_jp12x_splat .section_head{ font-size:12pt; font-weight:bold; letter-spacing:3px; border-bottom:solid 1px #1b110e; margin-bottom:5px; } div.ds_jp12x_splat .page_head{ text-align:center; width:600px; margin:22px 0px 0px 55px; padding:0px 0px 30px 0px; } div.ds_jp12x_splat .align_right{ text-align:right; } div.ds_jp12x_splat .align_left{ text-align:left; } div.ds_jp12x_splat .motivation{ display:inline-block; width:706px; min-height:35px; position:relative; } div.ds_jp12x_splat .virtue_flaw{ display:inline-block; width:227px; min-height:35px; position:relative; } div.ds_jp12x_splat .name{ display:inline-block; font-size:18pt; margin:0px 0px 9px 0px; width: 600px; height:16px; } div.ds_jp12x_splat a{ text-decoration:none; color:#1b110e; } div.ds_jp12x_splat .page_foot{ text-align:center; width:600px; margin:22px 0px 0px 55px; padding:0px 0px 30px 0px; position:absolute; bottom:12px; } div.ds_jp12x_splat .page_bio{ display:none; } div.ds_jp12x_splat .tab_bar{ position:absolute; top:-36px; right:-5px; z-index:3; background-image:url('http://cdn.obsidianportal.com/assets/142627/brass-tab-left2.png'); background-position:top center; background-repeat:no-repeat; height:39px; width:380px; text-align:center; } div.ds_jp12x_splat .tab{ display:inline-block; width:155px; padding:8px 0px 0px 0px; font-family:palatino; font-size:12pt; font-variant:small-caps; text-align:center; font-weight:bold; color:#1b110e; cursor:pointer; } div.ds_jp12x_splat .portrait_holder{ display:inline-block; position:relative; float:right; padding:0px 0px 0px 0px; margin:3px 3px 5px 10px; border-style:solid; border-width:1px; border-color:#050505; } div.ds_jp12x_splat .portrait_corner_top_left{ position:absolute; left:-4px; top:-4px; width:64px; height:64px; z-index:4; } div.ds_jp12x_splat .portrait_corner_top_right{ position:absolute; right:-4px; top:-4px; width:64px; height:64px; z-index:4; } div.ds_jp12x_splat .portrait_corner_bottom_left{ position:absolute; left:-4px; bottom:-4px; width:64px; height:64px; z-index:4; } div.ds_jp12x_splat .portrait_corner_bottom_right{ position:absolute; right:-4px; bottom:-4px; width:64px; height:64px; z-index:4; } div.ds_jp12x_splat .section_bio{ margin-bottom:0px; min-height:200px; } div.section a{ text-decoration:underline; }
Javascript
// Global Storage jp12x_splat_context = {}; /////////////////////////////////////////////////// // Event Hooks //////////////////////////////////// /////////////////////////////////////////////////// // Called immediately before the script fills the Span fields with data function jp12x_splat_dataPreLoad(opts){ // Set the tiffytable button aisleten.characters.tiffytableSubmit = '<button class="tiffytable_submit"><div class="tiffytable_submit_text">✓</div></button>'; aisleten.characters.tiffytablePlaceholder = 'Edit'; } // Called immediately after the script fills the Span fields with data, before tiffytable attachement function jp12x_splat_dataPostLoad(opts){ // Store global context for search by class name jp12x_splat_context = document.getElementById(opts['containerId']); // Set additional options opts['imagePath'] = 'http://omnichron.net/external/op/src/vampire/'; opts['context'] = document.getElementById(opts['containerId']); opts['debugThreshold'] = -1; //Convert interface elements jp12x_splat_convertLists(opts); jp12x_splat_convertPips(opts); jp12x_splat_convertChecks(opts); jp12x_splat_convertAreas(opts); jp12x_splat_convertTips(opts); } // Called immediately before the sheet's data is saved function jp12x_splat_dataPreSave(opts){ // Set additional options opts['context'] = document.getElementById(opts['containerId']); jp12x_splat_unconvertPips(opts); jp12x_splat_unconvertChecks(opts); jp12x_splat_unconvertAreas(opts); } // Called after any tiffytable field changes value function jp12x_splat_dataChange(opts){ // Identify a data change within a tooltip area and unlock the tooltip oParent = jp12x_splat_getElementsByClassName("dsf_" + opts['fieldName'],'span')[0].parentNode; if (oParent.className.match('has_tooltip')){ oParent.setAttribute("editLock","unlocked"); oParent.mouseOut(); } } /////////////////////////////////////////////////// // Pips Interface Control ///////////////////////// /////////////////////////////////////////////////// // Applies a bunch of pips functionality to the specified element function jp12x_splat_pips(oElement,opts){ // Store options oElement.setAttribute('optsImagePath',opts['imagePath']); oElement.setAttribute('optsIsEditable',opts['isEditable']); oElement.setAttribute('optsDebugThreshold',opts['debugThreshold']); // Gets the range of the element from its class name oElement.range = function(){ // Get the range from the element's class name var iRange = this.className.match(/pipsRange_[\d]+/)[0].substring(10); // Default if needed, and return if (iRange != 3 && iRange != 5 && iRange != 7 && iRange != 10){ this.error(1,"Invalid range specification in Pips Element (Element Class: " + this.className + ")"); return 10; } else return iRange; }; // Gets the field value from the embedded image or the text oElement.value = function(){ // Get the value from the image if there is one if (this.getElementsByTagName('img').length){ var sPath = this.getElementsByTagName('img')[0].src; var iValue = parseInt(sPath.substring(sPath.length - 9,sPath.length - 7),10); } // If there's no image, get the value from the text else{ var iValue = parseInt(this.innerHTML); if (this.innerHTML == '') iValue = 0; } // Check the value for bad data, default if needed, and return if (isNaN(iValue) || iValue > this.range() || iValue < 0){ this.error(1,"Invalid value for Pips Element (Element Class: " + this.className + ")"); return 0; } else return iValue; }; // Converts the associated span element's contents to a pips image oElement.showPips = function(){ // Get the image path from options or default if (this.getAttribute('optsImagePath')) var sPath = this.getAttribute('optsImagePath'); else{ this.error(2,'No imagePath specified in options for pips element (Element Class: ' + this.className + ')'); sPath = 'http://omnichron.net/external/op/src/vampire/'; } // Skip fields with a value of -1 if (this.value() == -1) return; // Replace the contents with the appropriate pips image this.innerHTML = '<img src="' + sPath + 'pips-' + this.padDigits(this.value(),2) + '-' + this.padDigits(this.range(),2) + '.png" />'; // Activate the pips this.activate(); }; // Converts the associated span element's contents to a text value oElement.showValue = function(){ // Replace the contents with the appropriate value string this.innerHTML = this.value(); }; // Assigns clickability to a pips image element oElement.activate = function(){ // Don't actualy activate anything if we're not in edit mode if (this.getAttribute('optsIsEditable') != 'true') return; // Activate the element's pips interface this.onclick = this.click; // Set the element's alt text this.title = 'Click to set value'; // Set the cursor for the item this.style.cursor = 'pointer'; }; // Click event handler for the pips interface oElement.click = function(e){ // Provide cross-browser support for the event information var oEvent; if (window.event) oEvent = window.event; else oEvent = e; // Set the pixel thresholds for each pip var totalPips = this.padDigits(this.range(),2); var aThresholds; aThresholds = [0,15,30,45,60,78,94,108,123,138]; // Get the pips image that was clicked as a pips object var oImage = this.getElementsByTagName('img')[0]; // Walk up the offset parent tree to get the true click coords var oTemp = oImage; var iX = oTemp.offsetLeft; if (oTemp.offsetParent){ while (oTemp = oTemp.offsetParent){ iX += oTemp.offsetLeft; } } // Determine which pip the click was on and change the image var iClickX = oEvent.clientX - iX; for (var iScore = this.range(); iScore >= 0; iScore--){ if (iClickX > aThresholds[iScore]){ // If the user clicks the current score, they probably want to reduce by one if ((iScore + 1) == this.value()){ oImage.src = oImage.src.substring(0,oImage.src.length - 9) + this.padDigits(iScore,2) + "-" + this.padDigits(this.range(),2) + ".png"; } else{ oImage.src = oImage.src.substring(0,oImage.src.length - 9) + this.padDigits(iScore + 1,2) + "-" + this.padDigits(this.range(),2) + ".png"; } // Once the image has been set, we're done return; // Call the onUpdate event this.onUpdate(); } } }; // Error handling function - alerts on errors if bug reporting is on oElement.error = function(iImportance,sText){ if (this.getAttribute('optsDebugThreshold')) var iThreshold = this.getAttribute('optsDebugThreshold'); else iThreshold = 0; if (iImportance < iThreshold){ alert(sText); } } // Converts a number to a string with prepended zeros to the specified character length oElement.padDigits = function(iNumber,iDigits){ var sNumber = iNumber.toString(); var sTemp = ''; if (iDigits > sNumber.length){ for (var i = 0; i < (iDigits - sNumber.length); i++){ sTemp += '0'; } } return sTemp + sNumber; } // On Update event function, typicaly overriden oElement.onUpdate = function(){ } // Return the pips element for ease of refference return oElement; } // Converts all properly classed spans in the context to pips elements function jp12x_splat_convertPips(opts){ // Get all the spans in the context, whatever it may be if (opts['context']) var aSpans = opts['context'].getElementsByTagName('span'); else var aSpans = document.getElementsByTagName('span'); // Convert all the potential values in the context to pips var pTemp = {}; for (var i = 0; i < aSpans.length; i++){ if (aSpans[i].className.match(/pips/)){ pTemp = jp12x_splat_pips(aSpans[i],opts); pTemp.showPips(); } } } // Converts all the pips in the context back to thier basic values for saving function jp12x_splat_unconvertPips(opts) { // Get the working context if (opts['context']) var aSpans = opts['context'].getElementsByTagName('span'); else var aSpans = document.getElementsByTagName('span'); // Flip all the pips in the context back to values for(var i = 0; i < aSpans.length; i++){ if(aSpans[i].className.match(/pips/)){ aSpans[i].showValue(); } } } /////////////////////////////////////////////////// // List Interface Control ///////////////////////// /////////////////////////////////////////////////// // Applies a bunch of list functionality to the specified element function jp12x_splat_list(oElement,opts){ // Store options oElement.setAttribute('optsContainerId',opts['containerId']); oElement.setAttribute('optsIsEditable',opts['isEditable']); oElement.setAttribute('optsDebugThreshold',opts['debugThreshold']); // Parses the number of columns the list has from its class name oElement.columns = function(){ // Get the column count from the element's class name var iColumns = this.className.match(/listColumns_[\d]+/)[0].substring(12); // Default if needed, and return if (isNaN(iColumns) || iColumns < 1){ this.error(1,"Invalid column count specification in List Element (Element Class: " + this.className + ")"); return 1; } else return iColumns; }; // Gets the list's list item template from the element based on class oElement.template = function(){ // The template is the first div in the list with the "template" class var aDivs = this.getElementsByTagName('div'); for (var i = 0; i < aDivs.length; i++){ if (aDivs[i].className.match(/template/)) return aDivs[i]; } // Create a semi-persistant default row template if needed if (!this.defaultTemplate){ this.defaultTemplate = document.createElement('div'); this.defaultTemplate.innerHTML = '<span class="dsf"></span>'; } // If we got here, there wasn't a template in the list, default and return this.error(1,"No template row found in List Element (Element Class: " + this.className + ")"); return this.defaultTemplate; }; // Gets an array of the fields in the template row oElement.fields = function(){ // This is easy assuming all the fields are span tags, and all the spans are fields return this.template().getElementsByTagName('span'); } // Gets an array of the rows in the list, excluding the template oElement.rows = function(){ // Initialize the list of rows var aRows = new Array(); // Getting the divs in the list the hard way to avoid nested divs making the cut var aElements = this.childNodes; var aDivs = new Array(); var iCounter = 0; for (var n = 0; n < aElements.length; n++){ if (aElements[n].tagName == 'DIV'){ aDivs[iCounter] = aElements[n]; iCounter++; } } // If we have multiple columns, then get the rows from inside each one if (this.columns() > 1){ var aTemp = new Array(); for (var x = 0; x < aDivs.length; x++){ if (!aDivs[x].className.match(/template/)){ aTemp = aDivs[x].getElementsByTagName('div'); for (var y = 0; y < aTemp.length; y++){ aRows[aRows.length] = aTemp[y]; } } } } // Otherwise just get them all from the main div else{ for (var i = 1; i < aDivs.length; i++){ aRows[aRows.length] = aDivs[i]; } } // Return the array of rows // This may have been dissacoiated by the splices, not sure yet return aRows; } // Generates a structure containing the list's data from the save object oElement.loadData = function(){ // Pattern match on the first field for simplicity's sake var iCounter = 0; var oData = {}; // Get the fields in order (doesn't allow missing fileds) var sClassPattern = this.fields()[0].className.match(/dsf_[\w\d]+/)[0].substring(4); while (dynamic_sheet_attrs[sClassPattern + this.padDigits(iCounter,2)] != undefined){ oData[iCounter] = new Array(); for (var i = 0; i < this.fields().length; i++){ oData[iCounter][i] = dynamic_sheet_attrs[this.fields()[i].className.match(/dsf_[\w\d]+/)[0].substring(4) + this.padDigits(iCounter,2)]; } iCounter++; } // Write the length oData.length = iCounter; // Write the completed data structure to the object this.data = oData; } // Generates a structure contianing the list's data form the list itself oElement.parseData = function(){ // Go through each row of each field and populate the structure var oData = {}; oData.length = 0; for (var i = 0; i < this.rows().length; i++){ oData[i] = new Array(); for (var n = 0; n < this.fields().length; n++){ oData[i][n] = this.rows()[i].getElementsByTagName('span')[n].innerHTML } oData.length = i + 1; } // Write the completed data structure to the object this.data = oData; } // Renders out the code for the list and puts it into the list element oElement.render = function(){ var sTemp = ''; var iCurrentColumn = 1; var iBreak = 0; var sClass = ''; // Add the first column opener if multiple columns, and calc first col break if (this.columns() > 1){ sTemp = '\n<div class="column column_spacing">'; iBreak += Math.floor(this.data.length / this.columns()) - 1; if (iCurrentColumn <= (this.data.length % this.columns())) iBreak++; } // Accumulate the list code for each row for (var i = 0; i < this.data.length; i++){ // Populate and class the fields for (var n = 0; n < this.fields().length; n++){ this.fields()[n].className = this.fields()[n].className.replace(/dsf_[\w\d]+/,this.fields()[n].className.match(/dsf_[\w\d]+/)[0] + this.padDigits(i,2)); this.fields()[n].innerHTML = this.data[i][n]; } // Add the list item to the code sTemp += this.template().innerHTML; // Reset the template if it was used for (var x = 0; x < this.fields().length; x++){ sClass = this.fields()[x].className.match(/dsf_[\w\d]+/)[0]; this.fields()[x].className = this.fields()[x].className.replace(/dsf_[\w\d]+/,sClass.substring(0,sClass.length - 2)); this.fields()[x].innerHTML = ''; } // Add column breaks where needed if (this.columns() > 1 && (i == iBreak)){ // Add the column opener for the last column if (iCurrentColumn == (this.columns() - 1)) sTemp += '</div>\n<div class="column">'; // Add the final column's column closer else if (i == (this.data.length - 1)) sTemp += '</div>'; // Add the column openers for other columns else sTemp += '</div>\n<div class="column column_spacing">'; // Update the column break and current column iCurrentColumn++; iBreak += Math.floor(this.data.length / this.columns()); if (iCurrentColumn <= (this.data.length % this.columns())) iBreak++; } } // Prepend the template to the list code sTemp = '<div class="template">' + this.template().innerHTML + '</div>' + sTemp; // Purge jquery expandos in explorer sTemp = sTemp.replace(/jQuery[\d]+="[\d]+"/g,''); // Put the code in the list this.innerHTML = sTemp; // Activate the interface if in edit mode if (this.getAttribute('optsIsEditable') == 'true'){ // Look through all the anchor elements in the list and activate by class name var aButtons = this.getElementsByTagName('a'); for (var y = 0; y < aButtons.length;y++){ if(aButtons[y].className.match(/listDelete/)) aButtons[y].onclick = this.deleteItem; else if(aButtons[y].className.match(/listPromote/)) aButtons[y].onclick = this.promoteItem; else if(aButtons[y].className.match(/listDemote/)) aButtons[y].onclick = this.demoteItem; } } // Hide them if not else{ // Look through all the anchor elements in the list and hide by class name var oContext = document.getElementById(this.getAttribute('optsContainerId')); if (oContext) var aButtons = oContext.getElementsByTagName('a'); else{ this.error(2,'No context specified in options for list element (Element Class: ' + this.className + ')'); var aButtons = document.getElementsByTagName('a'); } for (var y = 0; y < aButtons.length; y++){ if(aButtons[y].className.match(/interface/)) aButtons[y].style.display = 'none'; } } // Triger the list's onUpdate event this.onUpdate(); }; // Adds an blank element to the list oElement.addItem = function(){ // Get the latest data from the list this.parseData(); // Add a new row to the data, full of blank values var aRow = new Array(); for (var i = 0; i < this.fields().length; i++){ aRow[i] = ''; } this.data[this.data.length] = aRow; this.data.length++; // Re-render the list this.render(); }; // Deletes the specified element from the list oElement.deleteItem = function(){ // Activate the list the item belongs to var oItem = this.parentNode; if (oItem.parentNode.className.match(/list/)) var lList = oItem.parentNode; else var lList = oItem.parentNode.parentNode; // Stop here if we're editing things if (oItem.innerHTML.match(/input/)) return; // Delete the item from the DOM oItem.parentNode.removeChild(oItem); // Refresh the list to renew numbering lList.parseData(); lList.render(); }; // Moves the specified element up the list one place oElement.promoteItem = function(){ // Activate the list the item belongs to var oItem = this.parentNode; if (oItem.parentNode.className.match(/list/)) var lList = oItem.parentNode; else var lList = oItem.parentNode.parentNode; // Stop here if we're editing things if (oItem.innerHTML.match(/input/)) return; // Get the latest data from the list lList.parseData(); // Figure out what row number was clicked var sFieldClass = oItem.getElementsByTagName('span')[0].className.match(/dsf_[\w\d]+/)[0]; var sIndexString = sFieldClass.substring(sFieldClass.length - 2).replace(/^[0]+/,''); var iIndex = parseInt(sIndexString); // Stop right here if the clicked item is already at the top if (iIndex == 0) return; // Swap the row data with the one above it var aRowA = lList.data[iIndex]; var aRowB = lList.data[iIndex - 1]; lList.data[iIndex] = aRowB; lList.data[iIndex - 1] = aRowA; // Re-render the data lList.render(); }; // Moves the specified element down the list one place oElement.demoteItem = function(){ // Activate the list the item belongs to var oItem = this.parentNode; if (oItem.parentNode.className.match(/list/)) var lList = oItem.parentNode; else var lList = oItem.parentNode.parentNode; // Stop here if we're editing things if (oItem.innerHTML.match(/input/)) return; // Get the latest data from the list lList.parseData(); // Figure out what row number was clicked var sFieldClass = oItem.getElementsByTagName('span')[0].className.match(/dsf_[\w\d]+/)[0]; var sIndexString = sFieldClass.substring(sFieldClass.length - 2).replace(/^[0]+/,''); var iIndex = parseInt(sIndexString); // Stop right here if the clicked item is alreayd on the bottom if (iIndex == (lList.data.length - 1)) return; // Swap the row data with the one below it var aRowA = lList.data[iIndex]; var aRowB = lList.data[iIndex + 1]; lList.data[iIndex] = aRowB; lList.data[iIndex + 1] = aRowA; // Re-render the data lList.render(); }; // Error handling function - alerts on errors if bug reporting is on oElement.error = function(iImportance,sText){ if (this.getAttribute('optsDebugThreshold')) var iThreshold = this.getAttribute('optsDebugThreshold'); else iThreshold = 0; if (iImportance < iThreshold){ alert(sText); } } // Converts a number to a string with prepended zeros to the specified character length oElement.padDigits = function(iNumber,iDigits){ var sNumber = iNumber.toString(); var sTemp = ''; if (iDigits > sNumber.length){ for (var i = 0; i < (iDigits - sNumber.length); i++){ sTemp += '0'; } } return sTemp + sNumber; } // On Update event function, typicaly overriden oElement.onUpdate = function(){ } // Return the origenal element now that it's fully equipped return oElement; } // Converts all properly classed divs in the context to lists function jp12x_splat_convertLists(opts){ // Find all the divs on the page with "list" in their class name if (opts['context']) var aDivs = opts['context'].getElementsByTagName('div'); else var aDivs = document.getElementsByTagName('div'); var lTemp = {}; for (var i = 0; i < aDivs.length; i++){ if (aDivs[i].className.match(/list/)){ // Convert each element to a full featured list object lTemp = jp12x_splat_list(aDivs[i],opts); // Populate the list from the data variable lTemp.loadData(); lTemp.render(); // Assign the onUpdate function lTemp.onUpdate = function(){ jp12x_splat_convertPips(opts); jp12x_splat_convertChecks(opts); jp12x_splat_convertTips(opts); jp12x_splat_convertAreas(opts); aisleten.characters.bindAllFields(opts['slug'],opts['containerId']); //dst_devkit.bindDynamicAttributes(); } } } } /////////////////////////////////////////////////// // Text Area Edit Control ///////////////////////// /////////////////////////////////////////////////// // Core Textarea Class function jp12x_splat_area(oElement,opts){ // Store options oElement.setAttribute('optsIsEditable',opts['isEditable']); oElement.setAttribute('optsDebugThreshold',opts['debugThreshold']); // Attaches edit events to area text oElement.activate = function(){ // Don't activate the element if we're not in edit mode if (this.getAttribute('optsIsEditable') != 'true') return; // Activate the element oElement.onclick = this.edit; // Add default value if (this.innerHTML == '') this.innerHTML = 'Click to edit'; // Set the element's alt text this.title = 'Click to edit'; // Set the cursor for the item this.style.cursor = 'pointer'; }; // Converts the element to an editable area oElement.edit = function(){ // Abort click function if we just clicked submit if(this.getAttribute('eventLock') == 'locked'){ this.setAttribute('eventLock',null); return; } // Force submit any other area in the context var aAreas = jp12x_splat_getElementsByClassName('area','span'); for (var i = 0; i < aAreas.length; i++){ if (aAreas[i].getAttribute('status') == 'editing') aAreas[i].submit(); } // Set the editing flag this.setAttribute('status','editing'); // Disable click functionality this.onclick = null; // Set cursor this.style.cursor = 'text'; // Remove default if (this.innerHTML == 'Click to edit') this.innerHTML = ''; // Convert <br /> tags to line breaks var sText = this.innerHTML.replace(/<br>/g,'\n'); // Select dimensions and classes var iWidth = this.offsetWidth + parseInt(this.getAttribute('widthMod')); var iHeight = this.offsetHeight + parseInt(this.getAttribute('heightMod')); var sClasses = this.getAttribute('areaClasses'); // Convert content into form with button this.innerHTML = '<textarea class="' + sClasses + '" style="width:' + iWidth + 'px;height:' + iHeight + 'px;">' + sText + '</textarea>'; this.innerHTML += '<button class="submit_button area_submit" onClick="this.parentNode.submit();"><div class="area_submit_text">✓</div></button>'; // Set the user's focus to the textarea var focusRef = function(){oElement.getElementsByTagName('textarea')[0].focus();}; this.focusTimeout = setTimeout(focusRef,50); }; // Converts the edit box back into regular text form oElement.submit = function(){ // Get the data from the edit box var sContent = this.getElementsByTagName('textarea')[0].value.replace(/\n/g,'<br>'); // Remove the form elements this.innerHTML = sContent; // Reapply the default value if needed if (this.innerHTML == '') this.innerHTML = 'Click to edit'; // Lock out the click event until we're done this.setAttribute('eventLock','locked'); // Automatically unlock after a twentieth of a second var submitRef = function(){oElement.setAttribute('eventLock',null);}; this.timeout = setTimeout(submitRef,50); // Set pointer this.style.cursor = 'pointer'; // Reattach the click functionality this.onclick = this.edit; // Reset the editing flag this.setAttribute('status',null); // Call the onUpdate event this.onUpdate(); }; // On Update event function, typicaly overriden oElement.onUpdate = function(){ } // Error handling function - alerts on errors if bug reporting is on oElement.error = function(iImportance,sText){ if (this.getAttribute('optsDebugThreshold')) var iThreshold = this.getAttribute('debugThreshold'); else iThreshold = 0; if (iImportance < iThreshold){ alert(sText); } } // Return the element for ease of refference return oElement; } // Converts all properly classed divs in the context to lists function jp12x_splat_convertAreas(opts){ // Find all the spans on the page with "area" in their class name if (opts['context']) var aSpans = opts['context'].getElementsByTagName('span'); else var aSpans = document.getElementsByTagName('span'); var taTemp = {}; for (var i = 0; i < aSpans.length; i++){ if (aSpans[i].className.match(/area/)){ // Convert each element to a full featured list object taTemp = jp12x_splat_area(aSpans[i],opts); taTemp.activate(); // Load up custom parameters and such depending on class if (aSpans[i].className.match('is_tooltip')){ taTemp.setAttribute('widthMod',-9); taTemp.setAttribute('heightMod',-9); taTemp.setAttribute('areaClasses','area tip_area'); taTemp.onUpdate = function(){ oParent = this.parentNode; oParent.setAttribute("editLock","unlocked"); oParent.mouseOut(); }; } else{ taTemp.setAttribute('widthMod',-23); taTemp.setAttribute('heightMod',-6); taTemp.setAttribute('areaClasses','area'); } } } } // Sets the necesary class name on areas for themt o be saved function jp12x_splat_unconvertAreas(opts){ // Find all the spans on the page with "area" in their class name if (opts['context']) var aSpans = opts['context'].getElementsByTagName('span'); else var aSpans = document.getElementsByTagName('span'); // Add the necesary save key to the class name // Also close out any active edit boxes for (var i = 0; i < aSpans.length; i++){ if (aSpans[i].className.match(/area/)){ if (aSpans[i].innerHTML.match(/textarea/)) aSpans[i].submit(); if (aSpans[i].innerHTML == 'Click to edit') aSpans[i].innerHTML = ''; } } } /////////////////////////////////////////////////// // Check Interface Control //////////////////////// /////////////////////////////////////////////////// // Applies a bunch of pips functionality to the specified element function jp12x_splat_check(oElement,opts){ // Store options oElement.setAttribute('optsImagePath',opts['imagePath']); oElement.setAttribute('optsIsEditable',opts['isEditable']); oElement.setAttribute('optsDebugThreshold',opts['debugThreshold']); // Parses the title from the class name oElement.getTitle = function(){ // Get the column count from the element's class name var sTitle = this.className.match(/title_[\w\d\s]+/); if (sTitle) sTitle = sTitle[0].substring(6); return sTitle; }; // Gets the field value from the embedded image or the text oElement.value = function(){ // Get the value from the image if there is one if (this.getElementsByTagName('img').length){ var sPath = this.getElementsByTagName('img')[0].src; var sValue = sPath.substring(sPath.length - 5,sPath.length - 4); } // If there's no image, get the value from the text else{ var sValue = this.innerHTML; if (this.innerHTML == '') sValue = '0'; } // Check the value for bad data, default if needed, and return if (sValue != '1' && sValue != '0'){ this.error(1,"Invalid value for Check Element (Element Class: " + this.className + ")"); return 0; } else return sValue; }; // Converts the associated span element's contents to a pips image oElement.showCheck = function(){ // Get the image path from options or default if (this.getAttribute('optsImagePath')) var sPath = this.getAttribute('optsImagePath'); else{ this.error(2,'No imagePath specified in options for Checks element (Element Class: ' + this.className + ')'); sPath = 'http://omnichron.net/external/op/src/vampire/'; } // Replace the contents with the appropriate check image this.innerHTML = '<img src="' + sPath + 'check-' + this.value() + '.png" />'; // Activate the check this.activate(); }; // Converts the associated span element's contents to a text value oElement.showValue = function(){ // Replace the contents with the appropriate value string this.innerHTML = this.value(); }; // Assigns clickability to a pips image element oElement.activate = function(){ // Don't actualy activate anything if we're not in edit mode if (this.getAttribute('optsIsEditable') != 'true') return; // Activate the element's pips interface this.onclick = this.click; // Set the element's alt text this.title = this.getTitle(); if (!this.title) this.title = 'Click to set value'; // Set the cursor for the item this.style.cursor = 'pointer'; }; // Click event handler for the pips interface oElement.click = function(){ // Get the pips image that was clicked as a pips object var oImage = this.getElementsByTagName('img')[0]; // Determine which pip the click was on and change the image if (this.value() == "1") oImage.src = oImage.src.substring(0,oImage.src.length - 5) + "0.png"; else oImage.src = oImage.src.substring(0,oImage.src.length - 5) + "1.png"; // Call the onUpdate event this.onUpdate(); }; // Error handling function - alerts on errors if bug reporting is on oElement.error = function(iImportance,sText){ if (this.getAttribute('optsDebugThreshold')) var iThreshold = this.getAttribute('optsDebugThreshold'); else iThreshold = 0; if (iImportance < iThreshold){ alert(sText); } } // On Update event function, typicaly overriden oElement.onUpdate = function(){ } // Return the pips element for ease of refference return oElement; } // Converts all properly classed spans in the context to pips elements function jp12x_splat_convertChecks(opts){ // Get all the spans in the context, whatever it may be if (opts['context']) var aSpans = opts['context'].getElementsByTagName('span'); else var aSpans = document.getElementsByTagName('span'); // Convert all the potential values in the context to pips var pTemp = {}; for (var i = 0; i < aSpans.length; i++){ if (aSpans[i].className.match(/check/)){ pTemp = jp12x_splat_check(aSpans[i],opts); pTemp.showCheck(); } } } // Converts all the pips in the context back to thier basic values for saving function jp12x_splat_unconvertChecks(opts) { // Get the working context if (opts['context']) var aSpans = opts['context'].getElementsByTagName('span'); else var aSpans = document.getElementsByTagName('span'); // Flip all the pips in the context back to values for(var i = 0; i < aSpans.length; i++){ if(aSpans[i].className.match(/check/)){ aSpans[i].showValue(); } } } /////////////////////////////////////////////////// // Tool Tip Control /////////////////////////////// /////////////////////////////////////////////////// function jp12x_splat_tip(oElement,opts){ // Store options oElement.setAttribute('optsIsEditable',opts['isEditable']); oElement.setAttribute('optsDebugThreshold',opts['debugThreshold']); // Gets the tip display oElement.tip = function(){ // Search the link's context for the tip element var aSpans = this.getElementsByTagName('span'); for (var i = 0; i < aSpans.length; i++){ if (aSpans[i].className.match('is_tooltip')){ return aSpans[i]; } } return false; }; // Assigns event functionality to a field oElement.activate = function(){ // Register the hover events this.onmouseover = this.showTip; this.onmouseout = this.mouseOut; this.tip().onmouseout = this.mouseOut; // Don't actualy activate anything if we're not in edit mode if (this.getAttribute('optsIsEditable') != 'true') return; // Activate the element's edit event this.onmouseup = this.mouseUp; // Set the cursor for the item this.style.cursor = 'pointer'; }; // Shows the tool tip, event handler for mouseover oElement.showTip = function(){ // If we're not in edit mode and the tip is empty, show nothing if (this.getAttribute('optsIsEditable') != 'true' && (this.tip().innerHTML == '' || this.tip().innerHTML == 'undefined')) return; // Clear the hide timer if we're still over the element if (this.timeout){ clearTimeout(this.timeout); return; } // If we're editing the field, abort if (this.getAttribute("editLock") == "locked") return; // Capture the tool tip element var oTip = this.tip(); // Position the tooltip under the main element oTip.style.top = this.offsetHeight + 'px'; // Show the tool tip oTip.style.display = 'block'; }; // Hides the tool tip, event handler for mouseout oElement.hideTip = function(){ // Abort the hide if we're editing if (this.getAttribute("editLock") == "locked") return; // Hide the tool tip this.tip().style.display = 'none'; // Reset the hide timer this.timeout = false; }; // Handles the mouseout event for the tooltip oElement.mouseOut = function(){ // Abort the event completely if we're editing if (this.getAttribute("editLock") == "locked") return; // Delays the hide by a 20th of a second // This allows mouseover to cancel hide for sub elements var hideRef = function(){jp12x_splat_tip(oElement,opts).hideTip();}; this.timeout = setTimeout(hideRef,50); }; // Click event handler for the tool tip interface oElement.mouseUp = function(e){ // Cross browser event data getter var sClickedClass = ''; if (!e) sClickedClass = window.event.srcElement.className; else sClickedClass = e.target.className; // Abort out if a non-tiffytable thing was clicked if (!sClickedClass.match('dsf') || (sClickedClass.match('readonly') && !sClickedClass.match('area'))) return; // Hide the tooltip if that's not what we're editing if (!sClickedClass.match('is_tooltip')) this.hideTip(); // If we're not already editing, lock the tooltip if (this.getAttribute("editLock") != "locked") this.setAttribute("editLock","locked"); }; // Error handling function - alerts on errors if bug reporting is on oElement.error = function(iImportance,sText){ if (this.getAttribute('optsDebugThreshold')) var iThreshold = this.getAttribute('optsDebugThreshold'); else iThreshold = 0; if (iImportance < iThreshold){ alert(sText); } } // Return the pips element for ease of refference return oElement; } // Converts all properly classed divs in the context to pips elements function jp12x_splat_convertTips(opts){ // Get all the divs in the context, whatever it may be if (opts['context']) var aDivs = opts['context'].getElementsByTagName('div'); else var aDivs = document.getElementsByTagName('div'); // Convert all the potential values in the context to pips var pTemp = {}; for (var i = 0; i < aDivs.length; i++){ if (aDivs[i].className.match(/has_tooltip/)){ pTemp = jp12x_splat_tip(aDivs[i],opts); pTemp.activate(); } } } /////////////////////////////////////////////////// // General Utility Functions ////////////////////// /////////////////////////////////////////////////// // Gets an array of elements with a particular class from the context function jp12x_splat_getElementsByClassName(sClassName,sElementType){ // Provide default element type if (!sElementType) sElementType = 'div'; var aList = new Array(); var aDivs = jp12x_splat_context.getElementsByTagName(sElementType); for (var i = 0; i < aDivs.length; i++){ if (aDivs[i].className.match(sClassName)) aList[aList.length] = aDivs[i]; } return aList; } // Tab switching function function jp12x_splat_tabClick(oTab,sPageClass){ // Abort if already on the selected tab var oPage = jp12x_splat_getElementsByClassName('page_' + sPageClass)[0]; if (oPage.style.display != 'none') return; // Set the length of the shorter page to match the longer page var oPages = jp12x_splat_getElementsByClassName('main'); var iHeight = 0; for (var i = 0; i < oPages.length; i++){ if (oPages[i].offsetHeight > iHeight) iHeight = oPages[i].offsetHeight; } for (var n = 0; n < oPages.length; n++){ oPages[n].style.minHeight = (iHeight - 140) + 'px'; } // Corelate the 'type' fields on the two pages var aTypes = jp12x_splat_getElementsByClassName('dsf_type','span'); if (sPageClass == 'sheet'){ aTypes[0].innerHTML = aTypes[1].innerHTML; } else{ aTypes[1].innerHTML = aTypes[0].innerHTML; } // Show the proper pages and tabs if (sPageClass == 'sheet'){ oTab.parentNode.style.backgroundImage = "url(http://cdn.obsidianportal.com/assets/142627/brass-tab-left2.png)"; jp12x_splat_getElementsByClassName('page_sheet')[0].style.display = 'block'; jp12x_splat_getElementsByClassName('page_bio')[0].style.display = 'none'; } else{ oTab.parentNode.style.backgroundImage = "url(http://cdn.obsidianportal.com/assets/142628/brass-tab-right2.png)"; jp12x_splat_getElementsByClassName('page_bio')[0].style.display = 'block'; jp12x_splat_getElementsByClassName('page_sheet')[0].style.display = 'none'; } }
Submit Notes
Back